1. 程式人生 > >【CodeForces】CodeForces Round #406 (Div. 1) 題解

【CodeForces】CodeForces Round #406 (Div. 1) 題解

【比賽連結】

【題解連結】

**【A】**Berzerk

【思路要點】

  • 博弈搜尋,將狀態按先後手拆點,建出遊戲圖。
  • 若一個點存在出邊指向必敗態,則該點為必勝態。
  • 若一個點所有出邊指向必勝態,則該點為必敗態。
  • 不滿足上述兩點的點為平局態。
  • 用一個類似拓撲排序的過程實現即可。
  • 時間複雜度 O (
    N 2 ) O(N^2)

【程式碼】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e4 + 5
; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char
c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, tot, point[MAXN][2], d[MAXN]; bool vis[MAXN], win[MAXN]; vector <int> s, t, a[MAXN]; int main() { read(n); int k; read(k); while (k--) { int x; read(x); s.push_back(x); } read(k); while (k--) { int x; read(x); t.push_back(x); } for (int i = 1; i <= n; i++) { point[i][0] = ++tot; d[tot] = s.size(); point[i][1] = ++tot; d[tot] = t.size(); } int l = 0, r = 1; static int q[MAXN]; q[0] = point[1][0], q[1] = point[1][1]; vis[q[0]] = vis[q[1]] = true; win[q[0]] = win[q[1]] = false; while (l <= r) { int tmp = q[l++], type = tmp % 2; int pos = (tmp + 1) / 2; if (win[tmp]) { if (type) { for (unsigned i = 0; i < t.size(); i++) { int tnp = point[(pos - t[i] + n - 1) % n + 1][1]; if (!vis[tnp] && --d[tnp] == 0) { vis[tnp] = true; win[tnp] = false; q[++r] = tnp; } } } else { for (unsigned i = 0; i < s.size(); i++) { int tnp = point[(pos - s[i] + n - 1) % n + 1][0]; if (!vis[tnp] && --d[tnp] == 0) { vis[tnp] = true; win[tnp] = false; q[++r] = tnp; } } } } else { if (type) { for (unsigned i = 0; i < t.size(); i++) { int tnp = point[(pos - t[i] + n - 1) % n + 1][1]; if (!vis[tnp]) { vis[tnp] = true; win[tnp] = true; q[++r] = tnp; } } } else { for (unsigned i = 0; i < s.size(); i++) { int tnp = point[(pos - s[i] + n - 1) % n + 1][0]; if (!vis[tnp]) { vis[tnp] = true; win[tnp] = true; q[++r] = tnp; } } } } } for (int i = 2; i <= n; i++) if (vis[point[i][0]]) { if (win[point[i][0]]) printf("Win "); else printf("Lose "); } else printf("Loop "); printf("\n"); for (int i = 2; i <= n; i++) if (vis[point[i][1]]) { if (win[point[i][1]]) printf("Win "); else printf("Lose "); } else printf("Loop "); printf("\n"); return 0; }

**【B】**Legacy

【思路要點】

  • 線段樹建圖,跑單源最短路。
  • 時間複雜度 O ( N L o g N + Q L o g 2 N ) O(NLogN+QLog^2N)

【程式碼】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
namespace ShortestPath {
	const ll INF = 1e18;
	const int MAXP = 1e6;
	struct edge {int dest, len; };
	int n; ll dist[MAXP];
	vector <edge> a[MAXP];
	set <pair <ll, int> > st;
	void addedge(int x, int y, int z) {
		a[x].push_back((edge) {y, z});
	}
	void init(int x) {
		n = x; st.clear();
		for (int i = 1; i <= n; i++) {
			dist[i] = INF;
			a[i].clear();
		}
	}
	void work(int s) {
		dist[s] = 0;
		st.insert(make_pair(0, s));
		while (!st.empty()) {
			pair <ll, int> tmp = *st.begin();
			st.erase(tmp);
			for (unsigned i = 0; i < a[tmp.second].size(); i++) {
				int dest = a[tmp.second][i].dest;
				ll newlen = tmp.first + a[tmp.second][i].len;
				if (newlen < dist[dest]) {
					st.erase(make_pair(dist[dest], dest));
					dist[dest] = newlen;
					st.insert(make_pair(dist[dest], dest));
				}
			}
		}
	}
}
int tot, n, q, s, totp, root;
int lc[MAXN], rc[MAXN], point[MAXN][2];
void build(int &root, int l, int r) {
	root = ++totp;
	point[root][0] = ++tot;
	point[root][1] = ++tot;
	if (l == r) return;
	int mid = (l + r) / 2;
	build(lc[root], l, mid);
	build(rc[root], mid + 1, r);
}
void query(int from, int root, int l, int r, int ql, int qr, int len, int type) {
	if (l == ql && r == qr) {
		if (type == 0) ShortestPath :: addedge(from, point[root][0], len);
		else ShortestPath :: addedge(point[root][1], from, len);
		return;
	}
	int mid = (l + r) / 2;
	if (mid >= ql) query(from, lc[root], l, mid, ql, min(mid, qr), len, type);
	if (mid + 1 <= qr) query(from, rc[root], mid + 1, r, max(mid + 1, ql), qr, len, type);
}
int main() {
	read(n), read(q), read(s), tot = n;
	build(root, 1, n);
	ShortestPath :: init(tot);
	for (int i = 1, j = 0; i <= totp; i++) {
		if (lc[i]) {
			ShortestPath :: addedge(point[i][0], point[lc[i]][0], 0);
			ShortestPath :: addedge(point[i][0], point[rc[i]][0], 0);
			ShortestPath :: addedge(point[lc[i]][1], point[i][1]
            
           

相關推薦

CodeForcesCodeForces Round #406 (Div. 1) 題解

【比賽連結】 點選開啟連線 【題解連結】 點選開啟連結 **【A】**Berzerk 【思路要點】 博弈搜尋,將狀態按先後手拆點,建出遊戲圖。 若一個點存在出邊指向必敗態,則

CodeForcesCodeForces Round #512 (Div. 1) 題解

【比賽連結】 點選開啟連線 【題解連結】 點選開啟連結 **【A】**Vasya and Triangle 【思路要點】 任何三格點角形的面積均是

CodeForcesCodeForces Round #511 (Div. 1) 題解

【比賽連結】 點選開啟連線 【題解連結】 點選開啟連結 **【A】**Enlarge GCD 【思路要點】 令所有數的

CodeForcesCodeForces Round #516 (Div. 1) 題解

【比賽連結】 點選開啟連線 【題解連結】 點選開啟連結 **【A】**Oh Those Palindromes 【思路要點】 一個字串是迴文串的一個必要條件是該字串的第一個字元與最後

題解Codeforces 1063:Round #516 (Div. 1, by Moscow Team Olympiad) ABC

總結 字串排序後的迴文子串數最多,為ΣNx(Nx+1)/2\Sigma N_x(Nx+1)/2ΣNx​(Nx+1)/2 bfs獲得下一步狀態時,選擇遍歷常數陣列與分別列舉中適合的方案。 A. Oh Those Palindromes 迴文串,結論 給定一個

Codeforces Educational Round 54 Div. 2 A-G

傳送門:cf1076 A. Minimizing the String 貪心刪去第一個字典序大於後一個位置的字母的位置。 #include<bits/stdc++.h> using namespace std; int n; char s[200005];

Codeforces Round #516 (Div. 1) 題解

直線 () force ans ces 相互 wap col efi A.Oh Those Palindromes 直接排序之後輸出就行了。 證明的話直接跟據同一種字符最多能在多少個回文串中貢獻答案就行了。 #include <bits/stdc++.h> #

CodeChefSeptember Challenge 2018 (Div. 1 + Div. 2) 題解

【比賽連結】 點選開啟連線 **【ANDSQR】**AND Square Subsegments 【思路要點】 離線詢問,按左端點排序。 列舉區間的左端點

CodeChefOctober Challenge 2018 (Div. 1 + Div. 2) 題解

【比賽連結】 點選開啟連線 **【BBRICKS】**Beautiful Bricks 【思路要點】 上下兩個磚塊中,至多有一個黑色。 連續的一段存在黑色的行共有兩種放置的方案。 列舉有幾段連續的存在黑色的

洛谷 P3374 模板樹狀數組 1 題解

數字 pri getchar 說明 using 完全 ace getc ret 此文為博主原創題解,轉載時請通知博主,並把原文鏈接放在正文醒目位置。 題目鏈接:https://www.luogu.org/problem/show?pid=3374 題目描述 如題,

ContestNowcoder 假日團隊賽1 題解+賽後總結

比賽連結 通過順序:\(B\rightarrow D\rightarrow I\rightarrow J\rightarrow G\rightarrow H \rightarrow A \rightarrow K\rightarrow C\rightarrow E \rightarrow L \rightar

推導Codeforces Round #411 (Div. 1) A. Find Amir

div sca ace space for amp clu ret blog 1 2 3 4 5 6 7 4-5-3-6-2-7-1 答案是(n-1)/2 #include<cstdio> using namespace std; int n; int mai

動態規劃Codeforces Round #406 (Div. 2) C.Berzerk

[1] space node sca 一個 for 隊列 ber 動態規劃 有向圖博弈問題。 能轉移到一個必敗態的就是必勝態。 能轉移到的全是必勝態的就是必敗態。 轉移的時候可以用隊列維護。 可以看這個 http://www.cnblogs.com/quintessence

貪心 Codeforces Round #419 (Div. 1) A. Karen and Game

blog true 刪除 round 貪心 cnblogs pac names namespace 容易發現,刪除的順序不影響答案。 所以可以隨便刪。 如果行數大於列數,就先刪列;否則先刪行。 #include<cstdio> #include<algo

找規律遞推二項式定理Codeforces Round #419 (Div. 1) B. Karen and Test

main turn logs pow 分享 string ren () 奇數 打個表出來看看,其實很明顯。 推薦打這倆組 11 1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000

推導貪心Codeforces Round #431 (Div. 1) A. From Y to Y

aaa return 最大的 tchar 題意 spa 必須 puts clu 題意:讓你構造一個只包含小寫字母的可重集,每次可以取兩個元素,將它們合並,合並的代價是這兩個元素各自的從‘a’到‘z’出現的次數之積的和。 給你K,你構造的可重集必須滿足將所有元素合而為一以後,

codeforces比賽題解#868 CF Round #438 (Div.1+Div.2)

這一 一行 mes 無限 解鎖 col 道路 ces 然而 這次是Div.1+Div.2,所以有7題。 因為時間較早,而且正好趕上訓練,所以機房開黑做。 然而我們都只做了3題。:(。 鏈接。 【A】聲控解鎖 題意: Arkady的寵物狗Mu-mu有一只手機。它需要朝這個手機

做題Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆環

每一個 int 會有 while sig 實現 dex -s 怎麽辦 前言:結論題似乎是我的硬傷…… 題意是給你一個無向圖,已知連接到每一個點的邊的權值和(為整數,且屬於區間[-n,n]),需要求出每條邊權值的一個合法解(都要是在區間[-2*n^2,2*n^2]內的整數)。

Codeforces Round #239 (Div. 1) ATriangle

div urn end ont stdin a* 題意 sqrt 是不是 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 最後的直角三角形可以通過平移,將直角頂點移動到坐標原點。 然後我們只要枚舉另外兩個點其中一個點的坐標就好了。 x坐標

Codeforces Round #239 (Div. 1) B Long Path

pro tdi ont pre std [1] spa 鏈接 blog 【鏈接】 我是鏈接,點我呀:) 【題意】 在這裏輸入題意 【題解】 DP,設f[i]表示第一次到i這個房間的時候傳送的次數。 f[1] = 0,f[2] = 2 考慮第i個位置的情況。