제출 #211965

#제출 시각아이디문제언어결과실행 시간메모리
211965godwindMaking Friends on Joitter is Fun (JOI20_joitter2)C++14
0 / 100
13 ms16768 KiB
// O O O O O O O O O O O O O O O OO O OO O OO O O O TTCH O TTTCH O TTTCH O O O O #pragma GCC optimize("Ofast") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("fast-math") #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx") #include <iostream> #include <vector> #include <algorithm> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <stdio.h> #include <cstdio> #include <math.h> #include <cmath> #include <string> #include <cstring> #include <queue> #include <deque> // #include <random> #include <iomanip> #include <bitset> #include <cassert> using namespace std; #define int long long #define y1 y11 #define double long double #define less less228 #define left left228 #define right right228 #define list list228 #define all(v) v.begin(), v.end() template<typename T> void uin(T &a, T b) { if (b < a) a = b; } template<typename T> void uax(T &a, T b) { if (b > a) a = b; } const int N = 100 * 1000 + 228; int p[N], sz[N]; vector<int> in[N]; void init(int n) { for (int i = 1; i <= n; ++i) { p[i] = i; sz[i] = 1; in[i].emplace_back(i); } } int getp(int v){ if(v==p[v])return v; p[v]=getp(p[v]); return p[v]; } int n,m; int ans = 0; map< pair<int,int>, bool> is; map< pair<int,int>,int> between; set<int> vic[N], iic[N], outc[N]; void squeeze(int c1, int c2) { // cout << "squeeze " << c1 << " " << c2 << endl; ans -= between[{c1, c2}] * sz[c2]; ans -= between[{c2, c1}] * sz[c1]; ans += 2LL * sz[c1] * sz[c2]; // cout << "ans -= " << between[{c1, c2}] * sz[c2] << endl; // cout << "ans -= " << between[{c2, c1}] * sz[c1] << endl; // cout << "ans += 2 * " << sz[c1] << " * " << sz[c2] << endl; if (sz[c1] > sz[c2]) swap(c1, c2); // cout << "C1=" << c1 << " C2=" << c2 << endl; for (int x : in[c1]) { if (vic[c2].find(x) != vic[c2].end()) { vic[c2].erase(x); } } int izn = (int)vic[c2].size(); vector<int> suspicion; int cnt = 0; for (int x : vic[c1]) { if (getp(x) == c2) continue; if (!vic[c2].count(x)) { vic[c2].insert(x); ans += sz[c2]; suspicion.emplace_back(getp(x)); } else ++cnt; } // cout << "cnt=" << cnt << endl; ans += ((int)izn - cnt) * sz[c1]; // cout << "AAAns += " << izn - cnt << " * " << sz[c1] << endl; for (int c : iic[c1]) { if (getp(c) == c2 || c == c1) continue; if (!is[{c, c2}]) { is[{c, c2}] = 1; iic[c2].insert(c); suspicion.emplace_back(c); } between[{c, c2}] += between[{c, c1}]; } for (int c : outc[c1]) { if (getp(c) == c2 || c == c1) continue; if (!is[{c2, c}]) { is[{c2, c}] = 1; outc[c2].insert(c); suspicion.emplace_back(c); } between[{c2, c}] += between[{c1, c}]; } if (outc[c2].find(c1) != outc[c2].end()) { outc[c2].erase(c1); } p[c1] = c2; sz[c2] += sz[c1]; for (int x : in[c1]) { in[c2].emplace_back(x); } for (int c : suspicion) { if (is[{getp(c2), getp(c)}] && is[{getp(c), getp(c2)}]) { squeeze(getp(c), getp(c2)); } } } void add(int a, int b) { int c1 = getp(a); int c2 = getp(b); if (c1 == c2)return; // c1 --> c2 if (!is[{c2, c1}]) { is[{c1, c2}] = 1; iic[c2].insert(c1); outc[c1].insert(c2); if (!vic[c2].count(a)) { ++between[{c1, c2}]; ans += sz[c2]; vic[c2].insert(a); } } else { squeeze(c1, c2); } } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n >> m; init(n); for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; add(u, v); cout << ans << '\n'; } return 0; } // RU_023 /* 4 6 1 2 2 3 3 2 1 3 3 4 4 3 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...