Submission #64212

#TimeUsernameProblemLanguageResultExecution timeMemory
64212chpipisParachute rings (IOI12_rings)C++11
55 / 100
4027 ms76088 KiB
#if 0 #include <bits/stdc++.h> using namespace std; //#define TEST #define fi first #define se second #define mp make_pair #define pb push_back typedef long long ll; typedef pair<int, int> ii; const int len = 1e6; int n, state, cycle, last, t; int par[4][len], deg[4][len], sz[4][len], block[4][len], fine[4]; vector<int> adj[len]; vector<ii> edge; int fin(int i){ if (par[t][i] == i) return i; return par[t][i] = fin(par[t][i]); } void join(int i, int j){ i = fin(i), j = fin(j); if (i == j) return; if (sz[t][i] > sz[t][j]) sz[t][i] += sz[t][j], par[t][j] = i; else sz[t][j] += sz[t][i], par[t][i] = j; } void build(int u){ block[t][u] = 1; for (int i = 0; i < n; i++) par[t][i] = i, deg[t][i] = 0, sz[t][i] = 1; fine[t] = 1; for (int i = 0; i < edge.size(); i++){ int a = edge[i].fi, b = edge[i].se; if (!fine[t] || block[t][a] || block[t][b]) continue; if (deg[t][a] > 1 || deg[t][b] > 1 || fin(a) == fin(b)) fine[t] = 0; deg[t][a]++, deg[t][b]++; join(a, b); } } void Init(int N){ n = N, state = 0, cycle = 0, last = 0, t = 0; for (int i = 0; i < n; i++) par[0][i] = i, deg[0][i] = 0, sz[0][i] = 1; } void Link(int a, int b){ edge.pb(mp(a, b)); if (state == 0){ adj[a].pb(b), adj[b].pb(a); deg[0][a]++, deg[0][b]++; if (deg[0][a] < deg[0][b]) swap(a, b); if (deg[0][a] == 3){ state = 1; t = 0, build(a); t = 1, build(adj[a][0]); t = 2, build(adj[a][1]); t = 3, build(adj[a][2]); } else{ a = fin(a), b = fin(b); if (a == b) cycle++, last = sz[0][a]; else join(a, b); } } else{ for (t = 0; t < 4; t++){ if (!fine[t] || block[t][a] || block[t][b]) continue; if (deg[t][a] > 1 || deg[t][b] > 1 || fin(a) == fin(b)) fine[t] = 0; deg[t][a]++, deg[t][b]++; join(a, b); } } } int CountCritical(){ int ans = 0; if (state == 0){ if (cycle == 0) ans = n; else if (cycle == 1) ans = last; else ans = 0; } else{ for (int j = 0; j < 4; j++) ans += fine[j]; } return ans; } #ifdef TEST int main() { freopen("example.txt", "r", stdin); int tmp; /* Set input and output buffering */ char *inbuf, *outbuf; inbuf = (char*) malloc((1 << 16) * sizeof(char)); outbuf = (char*) malloc((1 << 16) * sizeof(char)); tmp = setvbuf(stdin, inbuf, _IOFBF, (1 << 16)); tmp = setvbuf(stdout, outbuf, _IOFBF, (1 << 16)); int N, L; tmp = scanf("%d %d", &N, &L); assert(tmp == 2); Init(N); int i; for (i = 0; i < L; i++) { int A, B; tmp = scanf("%d", &A); if (A == -1) { int critical; critical = CountCritical(); printf("%d\n", critical); } else { tmp = scanf("%d", &B); assert(tmp == 1); Link(A, B); } } return 0; } #endif // TEST #else #ifndef EVAL #include "grader.h" #endif #include <bits/stdc++.h> using namespace std; #define pb push_back const int MAXN = 1e6 + 5; vector<int> gr[MAXN]; int deg[MAXN], neig3[MAXN]; int p[MAXN], sz[MAXN]; int n, numcc, total, curcycle; int great_node, big; map<int, int> cnt; set<int> three; bool visit[MAXN]; void Init(int _n) { n = _n; for (int i = 0; i < n; i++) { neig3[i] = 0; deg[i] = 0; p[i] = -1; sz[i] = 1; gr[i].clear(); } three.clear(); numcc = n; total = n; big = 0; cnt.clear(); cnt[0] = n; } int fin(int x) { return (p[x] == -1 ? x : p[x] = fin(p[x])); } inline void chval(int x, int add) { if (deg[x] == 3) three.erase(x); cnt[deg[x]]--; if (cnt[deg[x]] == 0) cnt.erase(deg[x]); deg[x] += add; cnt[deg[x]]++; if (deg[x] == 3) three.insert(x); } void dfs(int u) { visit[u] = true; for (auto v : gr[u]) { if (visit[v]) continue; dfs(v); } } bool check(int w) { for (auto v : gr[w]) chval(v, -1); memset(visit, false, sizeof visit); visit[w] = true; chval(w, -((int)gr[w].size() + 1)); assert(cnt[1] % 2 == 0); int comps = cnt[0] + cnt[1] / 2; int want = 0; /* int how_many = 0; for (auto it : cnt) { if (it.first > 3) how_many += it.second; } */ for (int u = 0; u < n; u++) { if (!visit[u]) { want++; dfs(u); } } chval(w, +((int)gr[w].size() + 1)); for (auto v : gr[w]) chval(v, +1); return want == comps;// && how_many == 0; } char str[100]; void Link(int a, int b) { //str[0] = '\0'; if (deg[a] == 3) { for (auto v : gr[a]) neig3[v]--; big++; } if (deg[b] == 3) { for (auto v : gr[b]) neig3[v]--; big++; } chval(a, +1); chval(b, +1); gr[a].pb(b); gr[b].pb(a); if (deg[a] == 3) { for (auto v : gr[a]) neig3[v]++; } if (deg[b] == 3) { for (auto v : gr[b]) neig3[v]++; } if (deg[a] > 3) { great_node = a; } else if (deg[b] > 3) { great_node = b; } int ra = fin(a), rb = fin(b); if (ra != rb) { numcc--; if (sz[ra] > sz[rb]) { p[rb] = ra; sz[ra] += sz[rb]; } else { p[ra] = rb; sz[rb] += sz[ra]; } } else { curcycle = sz[ra]; } if (ra == rb) { if (big == 1 && fin(great_node) != ra) { total = 0; return; } else if (big == 0 && cnt[3] > 0 && fin(*three.begin()) != ra) { total = 0; return; } } if (big == 0 && cnt[3] == 0) { // everything is either a chain or a cycle assert(cnt[1] % 2 == 0); int comps = cnt[0] + cnt[1] / 2; if (comps == numcc) { // every component is a chain total = n; } else if (comps == numcc - 1) { total = curcycle; } else { //sprintf(str, "IMPOSSIBLE"); total = 0; } } else if (big > 1 || (false && cnt[3] > 4)) { /*if (big > 1) { if (cnt[3] > 4) sprintf(str, "big > 1 and cnt[3] > 4"); else sprintf(str, "big > 1"); } else { //sprintf(str, "cnt[3] > 4"); //sprintf(str, "cnt[0] = %d, cnt[1] = %d, cnt[2] = %d, cnt[3] = %d, cnt[4] = %d", cnt[0], cnt[1], cnt[2], cnt[3], cnt[4]); if (three.size() <= 5) { for (auto it : three) { sprintf(str + strlen(str), "%d ", it); } } }*/ total = 0; } else if (big == 1) { if (neig3[great_node] != (int)three.size()) { //sprintf(str, "impossible great_node"); total = 0; } else { bool found = (great_node == a || great_node == b); for (auto v : gr[a]) if (v == great_node) found = true; for (auto v : gr[b]) if (v == great_node) found = true; if (found || (ra == rb && total > 0)) { if (check(great_node)) { total = 1; } else { total = 0; //sprintf(str, "no great_node"); } } } } else if (big == 0 && cnt[3] > 0) { // now big = 0 and cnt[3] > 0 const int c = (int)three.size(); set<int> proc; for (auto u : three) { proc.insert(u); for (auto v : gr[u]) proc.insert(v); } bool found = false; for (auto it : proc) { if (it == a || it == b) found = true; } if (found || (ra == rb && total > 0)) { total = 0; for (auto u : proc) { if (deg[u] == 3 && neig3[u] == c - 1) { if (check(u)) total++; } else if (deg[u] < 3 && neig3[u] == c) { if (check(u)) total++; } } /* if (total == 0) sprintf(str, "no valid 3-degree nodes"); else sprintf(str, "there are 3-degree nodes"); */ } /* else { if (ra != rb || total == 0) return; total = 0; for (auto u : proc) { if (deg[u] == 3 && neig3[u] == c - 1) { if (check(u)) total++; } else if (deg[u] < 3 && neig3[u] == c) { if (check(u)) total++; } } }*/ } } int CountCritical() { //puts(str); return total; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...