1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| int w[N],v[N]; vector<int> G[N]; struct Tree_Chain_Dissection{ int idx[N],w[N]; int deep[N],fa[N],son[N],tot[N]; int cnt,top[N]; int dfs1(int a,int f,int dep){ deep[a]=deep[fa[a]=f]+1;tot[a]=1; int maxson=-1; for(auto v:G[a]) if(v!=f){ tot[a]+=dfs1(v,a,dep+1); if(tot[v]>maxson) maxson=tot[v],son[a]=v; } return tot[a]; } void dfs2(int a,int topf){ v[idx[a]=++cnt]=w[a];top[a]=topf; if(!son[a])return; dfs2(son[a],topf); for(auto v:G[a]) if(!idx[v])dfs2(v,v); } void Init(){ dfs1(rt,0,1);dfs2(rt,rt); Seg.build(1,n,1); } int Query_Chain(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]])swap(x,y); ans=(ans+Seg.query(idx[top[x]],idx[x],1,n,1))%mod; x=fa[top[x]]; } if(deep[x]>deep[y])swap(x,y); ans=(ans+Seg.query(idx[x],idx[y],1,n,1))%mod; return ans; } void Updata_Chain(int x,int y,int val){ while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]]) swap(x,y); Seg.updata(idx[top[x]],idx[x],val,1,n,1); x=fa[top[x]]; } if(deep[x]>deep[y]) swap(x,y); Seg.updata(idx[x],idx[y],val,1,n,1); } int Query_Tree(int x) {return Seg.query(idx[x],idx[x]+tot[x]-1,1,n,1);} void Updata_Tree(int x,int val) {Seg.updata(idx[x],idx[x]+tot[x]-1,val,1,n,1);} }TCD;
|