제출 #978810

#제출 시각아이디문제언어결과실행 시간메모리
978810MilosMilutinovicJOI tour (JOI24_joitour)C++17
100 / 100
2307 ms425724 KiB
#include "joitour.h" #define pb push_back #define fi first #define se second #define mp make_pair using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef long double ld; template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;} template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;} int n,tot,ct; int a[200005],v[400005],nxt[400005],h[200005],sz[200005],dfn[200005][20],dfo[200005][20],c[200005][3],cnt[200005][20][3],dep[200005],cf[200005][20],cr[200005][20]; bool vis[200005]; ll ans,cc[200005][3],ca[200005],pa[200005][20][3],sp[200005][3],pd[200005]; void addedge(int x,int y){ v[++tot]=y; nxt[tot]=h[x]; h[x]=tot; v[++tot]=x; nxt[tot]=h[y]; h[y]=tot; } struct fenwick{ int val[8000005]; fenwick(){ for(int i=1;i<=8000000;i++) val[i]=0; } void change(int p,int v){ for(;p<=8000000;p+=p&-p) val[p]+=v; } int ask(int p){ int v=0; for(;p;p-=p&-p) v+=val[p]; return v; } int ask(int l,int r){ return ask(r)-ask(l-1); } }sub[3],up[3]; void dfs1(int x,int f){ sz[x]=1; for(int p=h[x];p;p=nxt[p]){ if(v[p]==f||vis[v[p]]) continue; dfs1(v[p],x); sz[x]+=sz[v[p]]; } } int dfs2(int x,int f,int k){ for(int p=h[x];p;p=nxt[p]){ if(vis[v[p]]||v[p]==f||sz[v[p]]*2<k) continue; return dfs2(v[p],x,k); } return x; } void dfs3(int x,int f,int d,int rt,int r){ cf[x][d]=rt; cr[x][d]=r; c[rt][a[x]]++; cnt[r][d][a[x]]++; dfn[x][d]=++ct; for(int p=h[x];p;p=nxt[p]){ if(v[p]==f||vis[v[p]]) continue; dfs3(v[p],x,d,rt,r); } dfo[x][d]=++ct; if(a[x]==1){ pa[r][d][0]+=sub[0].ask(dfn[x][d]+1,dfo[x][d]); sp[rt][0]+=sub[0].ask(dfn[x][d]+1,dfo[x][d]); pa[r][d][2]+=sub[2].ask(dfn[x][d]+1,dfo[x][d]); sp[rt][2]+=sub[2].ask(dfn[x][d]+1,dfo[x][d]); } up[a[x]].change(dfn[x][d],1); up[a[x]].change(dfo[x][d],-1); sub[a[x]].change(dfn[x][d],1); } void build(int x,int d){ dfs1(x,x); x=dfs2(x,x,sz[x]); vis[x]=true; cf[x][d]=x; dep[x]=d; dfn[x][d]=++ct; for(int p=h[x];p;p=nxt[p]){ if(vis[v[p]]) continue; dfs3(v[p],x,d,x,v[p]); } for(int p=h[x];p;p=nxt[p]){ if(vis[v[p]]) continue; ans+=pa[v[p]][d][0]*1ll*(c[x][2]-cnt[v[p]][d][2]); ans+=pa[v[p]][d][2]*1ll*(c[x][0]-cnt[v[p]][d][0]); pd[x]+=(c[x][0]-cnt[v[p]][d][0])*1ll*cnt[v[p]][d][2]; pd[x]+=(c[x][2]-cnt[v[p]][d][2])*1ll*cnt[v[p]][d][0]; } dfo[x][d]=++ct; if(a[x]==0) ans+=sp[x][2]; if(a[x]==1) ans+=pd[x]/2; if(a[x]==2) ans+=sp[x][0]; for(int p=h[x];p;p=nxt[p]) if(!vis[v[p]]) build(v[p],d+1); } void init(int n,vector<int> f,vector<int> u,vector<int> v,int q){ ::n=n; for(int i=0;i+1<n;i++) addedge(u[i],v[i]); for(int i=0;i<n;i++) a[i]=f[i]; build(0,0); } void change(int x,int y){ if(a[x]==y) return; for(int d=0;d<=dep[x];d++){ if(cf[x][d]==x){ if(a[x]==0) ans-=sp[x][2]; if(a[x]==1) ans-=pd[x]/2; if(a[x]==2) ans-=sp[x][0]; if(y==0) ans+=sp[x][2]; if(y==1) ans+=pd[x]/2; if(y==2) ans+=sp[x][0]; continue; } if(a[cf[x][d]]==0) ans-=sp[cf[x][d]][2]; if(a[cf[x][d]]==1) ans-=pd[cf[x][d]]/2; if(a[cf[x][d]]==2) ans-=sp[cf[x][d]][0]; if(a[x]==1){ ans-=sub[0].ask(dfn[x][d]+1,dfo[x][d])*1ll*(c[cf[x][d]][2]-cnt[cr[x][d]][d][2]); ans-=sub[2].ask(dfn[x][d]+1,dfo[x][d])*1ll*(c[cf[x][d]][0]-cnt[cr[x][d]][d][0]); sp[cf[x][d]][0]-=sub[0].ask(dfn[x][d]+1,dfo[x][d]); sp[cf[x][d]][2]-=sub[2].ask(dfn[x][d]+1,dfo[x][d]); pa[cr[x][d]][d][0]-=sub[0].ask(dfn[x][d]+1,dfo[x][d]); pa[cr[x][d]][d][2]-=sub[2].ask(dfn[x][d]+1,dfo[x][d]); }else{ ans-=up[1].ask(dfn[x][d])*1ll*(c[cf[x][d]][2-a[x]]-cnt[cr[x][d]][d][2-a[x]]); ans-=sp[cf[x][d]][2-a[x]]-pa[cr[x][d]][d][2-a[x]]; sp[cf[x][d]][a[x]]-=up[1].ask(dfn[x][d]); pa[cr[x][d]][d][a[x]]-=up[1].ask(dfn[x][d]); pd[cf[x][d]]-=(c[cf[x][d]][2-a[x]]-cnt[cr[x][d]][d][2-a[x]])*2; } c[cf[x][d]][a[x]]-=1; cnt[cr[x][d]][d][a[x]]-=1; sub[a[x]].change(dfn[x][d],-1); up[a[x]].change(dfn[x][d],-1); up[a[x]].change(dfo[x][d],+1); if(y==1){ ans+=sub[0].ask(dfn[x][d]+1,dfo[x][d])*1ll*(c[cf[x][d]][2]-cnt[cr[x][d]][d][2]); ans+=sub[2].ask(dfn[x][d]+1,dfo[x][d])*1ll*(c[cf[x][d]][0]-cnt[cr[x][d]][d][0]); sp[cf[x][d]][0]+=sub[0].ask(dfn[x][d]+1,dfo[x][d]); sp[cf[x][d]][2]+=sub[2].ask(dfn[x][d]+1,dfo[x][d]); pa[cr[x][d]][d][0]+=sub[0].ask(dfn[x][d]+1,dfo[x][d]); pa[cr[x][d]][d][2]+=sub[2].ask(dfn[x][d]+1,dfo[x][d]); }else{ ans+=up[1].ask(dfn[x][d])*1ll*(c[cf[x][d]][2-y]-cnt[cr[x][d]][d][2-y]); ans+=sp[cf[x][d]][2-y]-pa[cr[x][d]][d][2-y]; sp[cf[x][d]][y]+=up[1].ask(dfn[x][d]); pa[cr[x][d]][d][y]+=up[1].ask(dfn[x][d]); pd[cf[x][d]]+=(c[cf[x][d]][2-y]-cnt[cr[x][d]][d][2-y])*2; } c[cf[x][d]][y]+=1; cnt[cr[x][d]][d][y]+=1; sub[y].change(dfn[x][d],+1); up[y].change(dfn[x][d],+1); up[y].change(dfo[x][d],-1); if(a[cf[x][d]]==0) ans+=sp[cf[x][d]][2]; if(a[cf[x][d]]==1) ans+=pd[cf[x][d]]/2; if(a[cf[x][d]]==2) ans+=sp[cf[x][d]][0]; } a[x]=y; } ll num_tours(){return ans;}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...