diff --git "a/khj20006/202509/03 BOJ D4 \352\267\270\353\236\230\355\224\204\354\231\200 \354\227\260\352\262\260\354\204\261 \354\277\274\353\246\254.md" "b/khj20006/202509/03 BOJ D4 \352\267\270\353\236\230\355\224\204\354\231\200 \354\227\260\352\262\260\354\204\261 \354\277\274\353\246\254.md" new file mode 100644 index 00000000..692fa0d4 --- /dev/null +++ "b/khj20006/202509/03 BOJ D4 \352\267\270\353\236\230\355\224\204\354\231\200 \354\227\260\352\262\260\354\204\261 \354\277\274\353\246\254.md" @@ -0,0 +1,127 @@ +```cpp +#pragma GCC optimize("O3, unroll-loops") +#include +using namespace std; +using ll = long long; + +int N, M, Q, bucketSize; +vector> edges; +vector> queries; +int res[100000]{}; + +// disjoint set +int root[100001]{}, cnt[100001]{}; +ll ans = 0; +vector> works; +ll g(ll x) { return x*(x-1)/2; } +void u(int a, int b) { + int x = a, y = b; + while(x != root[x]) x = root[x]; + while(y != root[y]) y = root[y]; + if(x == y) { + works.emplace_back(-1,-1,-1); + return; + } + if(cnt[x] > cnt[y]) swap(x,y); + works.emplace_back(x,y,cnt[x]); + ans -= g(cnt[x]) + g(cnt[y]); + cnt[y] += cnt[x]; + ans += g(cnt[y]); + root[x] = y; +} +void rollback() { + auto [x,y,r] = works.back(); works.pop_back(); + if(x == -1) return; + ans -= g(cnt[y]); + cnt[y] -= r; + ans += g(cnt[x]) + g(cnt[y]); + root[x] = x; +} + +// odc +int lifetime[100000]{}; +vector infos[262144]; +int need[100000]{}; +void update(int s, int e, int l, int r, int n, int i) { + if(l>r || l>e || r>1; + update(s,m,l,r,n*2,i); + update(m+1,e,l,r,n*2+1,i); +} +void clear(int s, int e, int n) { + for(int i:infos[n]) { + auto [a,b] = edges[i]; + u(a,b); + } + if(s == e) { + res[need[s]] = ans; + } + else { + int m = (s+e)>>1; + clear(s,m,n*2); + clear(m+1,e,n*2+1); + } + for(int i=0;isync_with_stdio(0); + cout.tie(0); + + cin>>N>>M>>Q; + bucketSize = sqrt(M); + iota(root, root+N+1, 0); + fill(cnt, cnt+N+1, 1); + + edges.resize(M); + for(auto &[a,b]:edges) cin>>a>>b; + + queries.resize(Q); + int tmp = 0; + for(auto &[a,b,c]:queries) cin>>a>>b, a--, b--, c=tmp++; + + sort(queries.begin(), queries.end(), [](auto a, auto b) -> bool{ + auto [al, ar, ax] = a; + auto [bl, br, bx] = b; + int anum = al/bucketSize, bnum = bl/bucketSize; + if(anum == bnum) { + if(anum & 1) return br < ar; + return ar < br; + } + return anum < bnum; + }); + + fill(lifetime, lifetime + M, -1); + int pl = 0, pr = 0, px = 0; + for(int i=0;i=l && lifetime[pr] == -1) lifetime[pr] = i; + } + while(r