제출 #578694

#제출 시각아이디문제언어결과실행 시간메모리
578694WongChun1234이상적인 도시 (IOI12_city)C++14
100 / 100
578 ms47496 KiB
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=100050; const ll MOD=1000000000; const bool DEBUG=0; int n,cx,cnt[N],grpcnt,ingrp[N]; ll ans,dist[N]; vector<pair<int,int>> curr,grps[N]; pair<int,int> coord[N]; map<int,vector<pair<int,int>>> mp; map<pair<int,int>,int> hv; ll f(ll num){ return (1+num)*num/2%MOD; } void dfs(int nde,int par,pair<int,int> connection,bool up){ vector<array<ll,2>> frntsum,frntcnt,bcksum,bckcnt; int cx=coord[grps[nde][0].second-1].first,cy=INT_MAX,cz=grps[nde].size(); ll csum=0,ccnt=0,lzsum=0,lzcnt=0,dup=0; frntsum.resize(cz); frntcnt.resize(cz); bcksum.resize(cz); bckcnt.resize(cz); if (DEBUG) cerr<<"dfs"<<cx<<"::"<<connection.first<<","<<connection.second<<"\n"; for (auto i:grps[nde]){ if (!hv[{cx+1,i.first}]) continue; if (ingrp[hv[{cx+1,i.first}]]==par) continue; cy=min(cy,i.first); if (hv[{cx+1,i.first+1}]&&i!=grps[nde].back()) continue; dfs(ingrp[hv[{cx+1,i.first}]],nde,{cy,i.first},0); cy=INT_MAX; } cy=INT_MAX; for (auto i:grps[nde]){ if (!hv[{cx-1,i.first}]) continue; if (ingrp[hv[{cx-1,i.first}]]==par) continue; cy=min(cy,i.first); if (hv[{cx-1,i.first+1}]&&i!=grps[nde].back()) continue; dfs(ingrp[hv[{cx-1,i.first}]],nde,{cy,i.first},1); cy=INT_MAX; } // down down, up up if (DEBUG) cerr<<"PROCESSING"<<ans<<"\n"; for (auto i:grps[nde]){ if (DEBUG) cerr<<cx<<","<<i.first<<"\n"; csum+=ccnt; csum%=MOD; lzsum+=lzcnt; lzsum%=MOD; if (DEBUG) cerr<<csum<<","<<ccnt<<";"<<lzsum<<","<<lzcnt<<":"<<ans<<"\n"; if (hv[{cx-1,i.first}]&&ingrp[hv[{cx-1,i.first}]]!=par){ lzcnt+=cnt[hv[{cx-1,i.first}]]; lzsum+=dist[hv[{cx-1,i.first}]]+cnt[hv[{cx-1,i.first}]]; lzcnt%=MOD; lzsum%=MOD; ans+=ccnt*(dist[hv[{cx-1,i.first}]]+cnt[hv[{cx-1,i.first}]]); ans+=csum*cnt[hv[{cx-1,i.first}]]; ans%=MOD; if (DEBUG) cerr<<ans<<"::\n"; }else{ csum+=lzsum; csum%=MOD; ccnt+=lzcnt; ccnt%=MOD; lzsum=lzcnt=0; } } csum=lzsum=ccnt=lzcnt=0; for (auto i:grps[nde]){ if (DEBUG) cerr<<cx<<","<<i.first<<"\n"; csum+=ccnt; csum%=MOD; lzsum+=lzcnt; lzsum%=MOD; if (DEBUG) cerr<<csum<<","<<ccnt<<";"<<lzsum<<","<<lzcnt<<":"<<ans<<"\n"; if (hv[{cx+1,i.first}]&&ingrp[hv[{cx+1,i.first}]]!=par){ lzcnt+=cnt[hv[{cx+1,i.first}]]; lzsum+=dist[hv[{cx+1,i.first}]]+cnt[hv[{cx+1,i.first}]]; lzcnt%=MOD; lzsum%=MOD; ans+=ccnt*(dist[hv[{cx+1,i.first}]]+cnt[hv[{cx+1,i.first}]]); ans+=csum*cnt[hv[{cx+1,i.first}]]; ans%=MOD; if (DEBUG) cerr<<ans<<"::\n"; }else{ csum+=lzsum; csum%=MOD; ccnt+=lzcnt; ccnt%=MOD; lzsum=lzcnt=0; } } // down to up for (int i=0;i<cz;i++){ if (i){ frntsum[i][0]=(frntsum[i-1][0]+frntcnt[i-1][0])%MOD; frntcnt[i][0]=frntcnt[i-1][0]; frntsum[i][1]=(frntsum[i-1][1]+frntcnt[i-1][1])%MOD; frntcnt[i][1]=frntcnt[i-1][1]; } dup+=ccnt; ccnt+=i+1; ccnt%=MOD; dup%=MOD; if (hv[{cx-1,grps[nde][i].first}]&&ingrp[hv[{cx-1,grps[nde][i].first}]]!=par){ frntcnt[i][0]+=cnt[hv[{cx-1,grps[nde][i].first}]]; frntsum[i][0]+=dist[hv[{cx-1,grps[nde][i].first}]]+cnt[hv[{cx-1,grps[nde][i].first}]]; frntsum[i][0]%=MOD; } if (hv[{cx+1,grps[nde][i].first}]&&ingrp[hv[{cx+1,grps[nde][i].first}]]!=par){ frntcnt[i][1]+=cnt[hv[{cx+1,grps[nde][i].first}]]; frntsum[i][1]+=dist[hv[{cx+1,grps[nde][i].first}]]+cnt[hv[{cx+1,grps[nde][i].first}]]; frntsum[i][1]%=MOD; } } for (int i=cz-1;~i;i--){ if (i!=cz-1){ bcksum[i][0]=(bcksum[i+1][0]+bckcnt[i+1][0])%MOD; bckcnt[i][0]=bckcnt[i+1][0]; bcksum[i][1]=(bcksum[i+1][1]+bckcnt[i+1][1])%MOD; bckcnt[i][1]=bckcnt[i+1][1]; } if (hv[{cx-1,grps[nde][i].first}]&&ingrp[hv[{cx-1,grps[nde][i].first}]]!=par){ bckcnt[i][0]+=cnt[hv[{cx-1,grps[nde][i].first}]]; bcksum[i][0]+=dist[hv[{cx-1,grps[nde][i].first}]]+cnt[hv[{cx-1,grps[nde][i].first}]]; bcksum[i][0]%=MOD; } if (hv[{cx+1,grps[nde][i].first}]&&ingrp[hv[{cx+1,grps[nde][i].first}]]!=par){ bckcnt[i][1]+=cnt[hv[{cx+1,grps[nde][i].first}]]; bcksum[i][1]+=dist[hv[{cx+1,grps[nde][i].first}]]+cnt[hv[{cx+1,grps[nde][i].first}]]; bcksum[i][1]%=MOD; } } if (DEBUG) for (int i=0;i<cz;i++) cerr<<frntsum[i][0]<<" "<<frntsum[i][1]<<" "<<frntcnt[i][0]<<" "<<frntcnt[i][1]<<"\n"; for (int i=0;i<cz;i++){ ans+=bcksum[i][0]+bcksum[i][1]; ans%=MOD; if (i) ans+=frntsum[i-1][0]+frntsum[i-1][1]+frntcnt[i-1][0]+frntcnt[i-1][1]; ans%=MOD; if (DEBUG) cerr<<cx<<","<<grps[nde][i].first<<":"<<ans<<"\n"; if (!hv[{cx+1,grps[nde][i].first}]||ingrp[hv[{cx+1,grps[nde][i].first}]]==par) continue; ans+=(dist[hv[{cx+1,grps[nde][i].first}]]+cnt[hv[{cx+1,grps[nde][i].first}]])%MOD*bckcnt[i][0]; ans%=MOD; ans+=bcksum[i][0]*cnt[hv[{cx+1,grps[nde][i].first}]]; ans%=MOD; if (i){ ans+=(dist[hv[{cx+1,grps[nde][i].first}]]+cnt[hv[{cx+1,grps[nde][i].first}]])%MOD*frntcnt[i-1][0]; ans%=MOD; ans+=(frntsum[i-1][0]+frntcnt[i-1][0])*cnt[hv[{cx+1,grps[nde][i].first}]]; ans%=MOD; } if (DEBUG) cerr<<cx<<","<<grps[nde][i].first<<":"<<ans<<"\n"; } for (int i=0;i<cz;i++){ if (up){ cnt[hv[{cx,grps[nde][i].first}]]=cnt[hv[{cx-1,grps[nde][i].first}]]+1; dist[hv[{cx,grps[nde][i].first}]]=dist[hv[{cx-1,grps[nde][i].first}]]+cnt[hv[{cx-1,grps[nde][i].first}]]; dist[hv[{cx,grps[nde][i].first}]]%=MOD; }else{ cnt[hv[{cx,grps[nde][i].first}]]=cnt[hv[{cx+1,grps[nde][i].first}]]+1; dist[hv[{cx,grps[nde][i].first}]]=dist[hv[{cx+1,grps[nde][i].first}]]+cnt[hv[{cx+1,grps[nde][i].first}]]; dist[hv[{cx,grps[nde][i].first}]]%=MOD; } if (grps[nde][i].first==connection.first){ if (i){ cnt[hv[{cx,grps[nde][i].first}]]+=frntcnt[i-1][0]+frntcnt[i-1][1]+i; dist[hv[{cx,grps[nde][i].first}]]+=frntsum[i-1][0]+frntsum[i-1][1]+frntcnt[i-1][0]+frntcnt[i-1][1]+f(i); dist[hv[{cx,grps[nde][i].first}]]%=MOD; } } if (grps[nde][i].first==connection.second){ if (i<cz-1){ cnt[hv[{cx,grps[nde][i].first}]]+=bckcnt[i+1][0]+bckcnt[i+1][1]+cz-i-1; dist[hv[{cx,grps[nde][i].first}]]+=bcksum[i+1][0]+bcksum[i+1][1]+bckcnt[i+1][0]+bckcnt[i+1][1]+f(cz-i-1); dist[hv[{cx,grps[nde][i].first}]]%=MOD; } } if (DEBUG) cerr<<cx<<":::"<<grps[nde][i].first<<":"<<cnt[hv[{cx,grps[nde][i].first}]]<<","<<dist[hv[{cx,grps[nde][i].first}]]<<"\n"; } for (int i=0;i<cz;i++) ans+=f(i); } void addgrp(){ grps[++grpcnt]=curr; for (auto i:curr) ingrp[i.second]=grpcnt; curr.clear(); } int DistanceSum(int _N, int *x, int *y) { n=_N; for (int i=0;i<n;i++) coord[i]={x[i],y[i]}; sort(coord,coord+n); for (int i=0;i<n;i++){ hv[coord[i]]=i+1; mp[coord[i].first].push_back({coord[i].second,i+1}); } for (auto i:mp){ cx=i.first; curr.clear(); for (auto j:i.second){ if (curr.empty()||j.first==curr.back().first+1){ curr.push_back(j); }else{ addgrp(); curr.push_back(j); } } if (curr.size()) addgrp(); } dfs(1,1,{-1,-1},0); return ans; } /* 6 1 1 2 1 2 3 3 1 3 2 3 3 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...