Submission #245579

#TimeUsernameProblemLanguageResultExecution timeMemory
245579kostia244Making Friends on Joitter is Fun (JOI20_joitter2)C++17
100 / 100
4081 ms116192 KiB
#pragma GCC optimize("O2,unroll-loops") #pragma GCC target("avx,avx2,sse,sse2,ssse3,popcnt") #include<bits/stdc++.h> #define all(x) x.begin(), x.end() using namespace std; using ll = long long; struct edge { int f, t, ri, r = 0; edge(int f, int t, int ri) : f(f), t(t), ri(ri) {} }; struct dsu { ll ans = 0, T = 69; vector<int> r, p, w, tbd; vector<vector<int>> g, gr; map<pair<int, int>, int> ctc, rtc; vector<edge> ve; queue<int> mrg; int have(int i, int j) { return ctc[{i, j}]; } void add(int i, int j) { ctc[{i, j}]++; } void rem(int i, int j) { ctc[{i, j}]--; } void iadd(int i, int j) { rtc[{i, j}]++; } void irem(int i, int j) { rtc[{i, j}]--; } int ihave(int i, int j) { return rtc[{i, j}]; } dsu(int n) : r(n+1, 1), p(n+1), g(n+1), gr(n+1), w(n+1), tbd(n+1) {iota(all(p), 0);} int par(int i) { return p[i] == i ? i : p[i] = par(p[i]); } int unite(int i, int j) { //cout << i << " " << j << endl; if(r[i] < r[j]) swap(i, j); //cout << i << " " << j << " | " << r[i] << " " << r[j] << " " << w[i] << " " << w[j] << endl; ans -= r[i]*1ll*(r[i]+w[i]-1) + r[j]*1ll*(r[j]+w[j]-1); //cout << ans << endl; w[i] += w[j]; r[i] += r[j]; p[j] = i; for(int U = 0; U < 2; U++) for(auto &x : (U?gr:g)[j]) { auto &e = ve[x]; if(e.r) continue; rem(e.f, e.t); irem(e.ri, e.t); if(U) e.t = i; else e.f = i; int p = U?e.f:e.t;assert(p == (e.f^e.t^i)); if(tbd[p] != T && have(e.t, e.f)) { mrg.push(p); tbd[p] = T; } if(ihave(e.ri, e.t) || e.f == e.t) {e.r = 1, w[i]--; continue;}//fucking useless (U?gr:g)[i].push_back(x); add(e.f, e.t); iadd(e.ri, e.t); } //cout << r[i] << " " << w[i] << endl; ans += r[i]*1ll*(r[i]+w[i]-1); return i; } void adde(int i, int j) { ++T; int ri = i; //cout << i << " " << j << " "; i = par(i), j = par(j); //cout << i << " " << j << "\n"; if(i == j) return; if(ihave(ri, j)) return; w[j]++, ans += r[j]; ve.emplace_back(i, j, ri); g[i].push_back(ve.size()-1); gr[j].push_back(ve.size()-1); add(i, j); iadd(ri, j); if(have(j, i)) { int cur = i; tbd[i] = tbd[j] = T; mrg.push(j); while(!mrg.empty()) { cur = unite(cur, mrg.front()); mrg.pop(); } } } }; int main() { cin.tie(0)->sync_with_stdio(0); int n, m; cin >> n >> m; dsu d(n); for(int f, t, i = 0; i < m; i++) { cin >> f >> t; d.adde(f, t); cout << d.ans << endl; } }

Compilation message (stderr)

joitter2.cpp: In constructor 'dsu::dsu(int)':
joitter2.cpp:14:25: warning: 'dsu::gr' will be initialized after [-Wreorder]
  vector<vector<int>> g, gr;
                         ^~
joitter2.cpp:13:20: warning:   'std::vector<int> dsu::w' [-Wreorder]
  vector<int> r, p, w, tbd;
                    ^
joitter2.cpp:24:2: warning:   when initialized here [-Wreorder]
  dsu(int n) : r(n+1, 1), p(n+1), g(n+1), gr(n+1), w(n+1), tbd(n+1) {iota(all(p), 0);}
  ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...