제출 #736220

#제출 시각아이디문제언어결과실행 시간메모리
736220becaido낙하산 고리들 (IOI12_rings)C++17
0 / 100
1844 ms148936 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx,popcnt,sse4,abm") #include <bits/stdc++.h> using namespace std; #ifdef WAIMAI #define debug(HEHE...) cout << "[" << #HEHE << "] : ", dout(HEHE) void dout() {cout << '\n';} template<typename T, typename...U> void dout(T t, U...u) {cout << t << (sizeof...(u) ? ", " : ""), dout(u...);} #else #define debug(...) 7122 #endif #define ll long long #define Waimai ios::sync_with_stdio(false), cin.tie(0) #define FOR(x,a,b) for (int x = a, I = b; x <= I; x++) #define pb emplace_back #define F first #define S second const int SIZE = 1e6 + 5; int n, mxdeg; vector<int> adj[SIZE]; struct DS { int p, mxD; int cycle, csum; int to[SIZE], sz[SIZE], sum[SIZE], deg[SIZE], mxdeg[SIZE]; void init() { mxD = cycle = csum = 0; iota(to + 1, to + n + 1, 1); fill(sz + 1, sz + n + 1, 1); fill(sum + 1, sum + n + 1, 0); fill(deg + 1, deg + n + 1, 0); fill(mxdeg + 1, mxdeg + n + 1, 0); } void build(int P = 0) { p = P; init(); FOR (i, 1, n) for (int j : adj[i]) if (i < j) Merge(i, j); } int dsu(int x) { return x == to[x] ? x : (to[x] = dsu(to[x])); } void add(int x) { if (mxdeg[x] == 2 && sz[x] == sum[x]) cycle++, csum = sz[x]; mxD = max(mxD, min(mxdeg[x], 4)); } void del(int x) { if (mxdeg[x] == 2 && sz[x] == sum[x]) cycle--; } void Merge(int a, int b) { if (a == p || b == p) return; int da = dsu(a), db = dsu(b); if (da == db) del(da); else del(da), del(db); sum[da] -= deg[a] == 2; sum[db] -= deg[b] == 2; mxdeg[da] = max(mxdeg[da], ++deg[a]); mxdeg[db] = max(mxdeg[db], ++deg[b]); sum[da] += deg[a] == 2; sum[db] += deg[b] == 2; if (da == db) { add(da); return; } if (sz[da] < sz[db]) swap(da, db); to[db] = da; sz[da] += sz[db]; sum[da] += sum[db]; mxdeg[da] = max(mxdeg[da], mxdeg[db]); add(da); } } ori, ds[4]; void Init(int N) { n = N; ori.build(); } void Link(int a, int b) { a++, b++; if (a > b) swap(a, b); adj[a].pb(b); adj[b].pb(a); ori.Merge(a, b); int cur = ori.mxD; if (cur == mxdeg + 1) { if (cur == 4) { FOR (i, 1, n) if (adj[i].size() == 4) { ds[0].build(i); break; } } if (cur == 3) { FOR (i, 1, n) if (adj[i].size() == 3) { ds[0].build(i); int k = 0; for (int j : adj[i]) ds[++k].build(j); break; } } } mxdeg = cur; if (mxdeg == 4) ds[0].Merge(a, b); else if (mxdeg == 3) FOR (i, 0, 3) ds[i].Merge(a, b); } int CountCritical() { if (mxdeg <= 1) return n; if (mxdeg == 2) return ori.cycle == 0 ? n : ori.cycle == 1 ? ori.csum : 0; int ans = 0; FOR (i, 0, (mxdeg == 3 ? 3 : 0)) ans += ds[i].mxD <= 1 || (ds[i].mxD == 2 && ds[i].cycle == 0); return ans; }
#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...