제출 #978852

#제출 시각아이디문제언어결과실행 시간메모리
978852Mr_Husanboy조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++17
100 / 100
1268 ms67744 KiB
//#pragma GCC optimize("Ofast,O3") //#pragma GCC target("avx,avx2") #include <bits/stdc++.h> using namespace std; #ifdef LOCAL #include "debugger.cpp" #else #define debug(...) #endif template<class T> int len(T &a){ return a.size(); } using ll = long long; using pii = pair<int,int>; #define all(a) (a).begin(), (a).end() #define ff first #define ss second string fileio = ""; mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); const int MOD = 1e9 + 7; const int inf = 1e9; const ll infl = 1e18; const int maxn = 1e5 + 1; struct DSU{ vector<int> par, sz; int n; DSU (int _n){ n = _n; par.resize(n); iota(all(par), 0); sz.assign(n, 1); } DSU (){} int get(int a){ return (par[a] == a ? a : par[a] = get(par[a])); } void init(int _n){ n = _n; par.resize(n); iota(all(par), 0); sz.assign(n, 1); } void unite(int a, int b){ a = get(a); b = get(b); if(a == b) return; if(sz[a] < sz[b]) swap(a,b); sz[a] += sz[b]; par[b] = a; } void link(int a, int b){ a = get(a); b = get(b); if(a == b) return; sz[b] += sz[a]; par[a] = b; } }; void solve(){ int n, m; cin >> n >> m; vector<set<int>> half(n), rhalf(n); vector<set<int>> lead(n); for(int i = 0; i < n; i ++) lead[i].insert(i); DSU t(n); ll ans = 0; queue<pair<int,int>> q; auto half_edge = [&](int a, int b){ //debug(a + 1, b + 1); half[a].insert(b); rhalf[b].insert(a); if(half[b].count(a)){ q.push({a, b}); } }; while(m --){ int a, b; cin >> a >> b; a --; b --; int la = t.get(a), lb = t.get(b); if(la == lb || lead[lb].count(a)){ cout << ans << '\n'; continue; } lead[lb].insert(a); half_edge(la, lb); ans += t.sz[lb]; while(!q.empty()){ tie(a, b) = q.front(); q.pop(); a = t.get(a), b = t.get(b); if(a == b) continue; ans += 1ll * t.sz[a] * len(lead[b]) + 1ll * t.sz[b] * len(lead[a]); if(len(lead[a]) > len(lead[b])) swap(a, b); t.link(a, b); for(auto u : lead[a]){ if(lead[b].count(u)) ans -= t.sz[b]; else lead[b].insert(u); } lead[a].clear(); half[a].erase(b); half[b].erase(a); rhalf[b].erase(a); rhalf[a].erase(b); for(auto i : half[a]){ rhalf[i].erase(b); half_edge(b, i); } for(auto i : rhalf[a]){ half[i].erase(a); half_edge(i, b); } } cout << ans << '\n'; } } int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); auto start = chrono::high_resolution_clock::now(); #ifndef LOCAL if(fileio.size()){ freopen((fileio + ".in").c_str(), "r", stdin); freopen((fileio + ".out").c_str(), "w", stdout); } #endif int testcases = 1; #ifdef Tests cin >> testcases; #endif while(testcases --){ solve(); if(testcases) cout << '\n'; #ifdef LOCAL else cout << '\n'; cout << "_________________________" << endl; #endif } #ifdef LOCAL auto duration = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - start); cout << "time: " << (double)duration.count()/1000.0 << " milliseconds" << endl; #endif return 0; }

컴파일 시 표준 에러 (stderr) 메시지

joitter2.cpp: In function 'int main()':
joitter2.cpp:138:10: warning: variable 'start' set but not used [-Wunused-but-set-variable]
  138 |     auto start = chrono::high_resolution_clock::now();
      |          ^~~~~
joitter2.cpp:141:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |         freopen((fileio + ".in").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
joitter2.cpp:142:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  142 |         freopen((fileio + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...