Submission #596653

#TimeUsernameProblemLanguageResultExecution timeMemory
596653Bench0310Ideal city (IOI12_city)C++17
100 / 100
463 ms55724 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1000000000; int add(int a,int b){return a+b-(a+b>=mod?mod:0);} int mul(int a,int b){return (ll(a)*b)%mod;} int res=0; const int N=100000; int n; vector<array<int,2>> tree[4*N]; vector<array<int,4>> upd[4*N]; int p[N]; int sz[N]; int events=0; int find_set(int a) { if(a==p[a]) return a; else return find_set(p[a]); } void merge_sets(int a,int b,vector<array<int,4>> &u) { a=find_set(a); b=find_set(b); if(a==b) return; if(sz[a]<sz[b]) swap(a,b); u.push_back({b,p[b],a,sz[a]}); p[b]=a; sz[a]+=sz[b]; } void apply(int idx,int l,int r,int ql,int qr,int a,int b) { if(ql>qr) return; if(l==ql&&r==qr) tree[idx].push_back({a,b}); else { int m=(l+r)/2; apply(2*idx,l,m,ql,min(qr,m),a,b); apply(2*idx+1,m+1,r,max(ql,m+1),qr,a,b); } } void process(int idx,int l,int r) { for(auto [a,b]:tree[idx]) merge_sets(a,b,upd[idx]); if(l<r) { int m=(l+r)/2; process(2*idx,l,m); process(2*idx+1,m+1,r); } else res=add(res,mul(sz[find_set(0)],n-sz[find_set(0)])); reverse(upd[idx].begin(),upd[idx].end()); for(auto [a,b,c,d]:upd[idx]){p[a]=b; sz[c]=d;} } void go(int *X,int *Y) { vector<array<int,2>> blocks(n); for(int i=0;i<n;i++) blocks[i]={X[i],Y[i]}; for(int i=0;i<n;i++) { p[i]=i; sz[i]=1; } events=0; map<array<int,2>,int> m; for(int i=0;i<n;i++) m[{X[i],Y[i]}]=i; auto id=[&](int x,int y) { if(m.find({x,y})!=m.end()) return m[{x,y}]; else return -1; }; vector<array<int,4>> v; for(int i=0;i<n;i++) { int t=id(X[i]+1,Y[i]); if(t!=-1) v.push_back({X[i],Y[i],i,t}); int j=id(X[i],Y[i]+1); if(j!=-1) merge_sets(i,j,upd[0]); } sort(v.begin(),v.end()); int len=v.size(); vector<array<int,2>> groups; int l=0; while(l<len) { int r=l; while(r+1<len&&v[r+1][0]==v[l][0]&&v[r][1]+1==v[r+1][1]) r++; groups.push_back({l,r}); events++; l=r+1; } for(int i=1;i<=events;i++) { auto [one,two]=groups[i-1]; for(int j=one;j<=two;j++) { if(i-1>=1) apply(1,1,events,1,i-1,v[j][2],v[j][3]); if(i+1<=events) apply(1,1,events,i+1,events,v[j][2],v[j][3]); } } process(1,1,events); //spring cleaning for(int i=0;i<4*N;i++) { tree[i].clear(); upd[i].clear(); } } int DistanceSum(int _n,int *x,int *y) { n=_n; go(x,y); go(y,x); return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...