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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| int head[maxn]; int to[maxn*2],nex[maxn*2],tot; inline void _addedge(int u,int v){to[++tot]=v,nex[tot]=head[u],head[u]=tot;} inline void addedge(int u,int v){_addedge(u,v),_addedge(v,u);} void deltree(int rt,int father){ for(int i=head[rt];i;i=nex[i]) if(to[i]!=father) deltree(to[i],rt); head[rt]=0; }
int pw[maxn*2]={1},hshmod; int *hsh,siz[maxn]; int *ehsh; void dfs(int u,int father){ siz[u]=1; for(int i=head[u];i;i=nex[i]){ if(to[i]==father)continue; dfs(to[i],u), siz[u]+=siz[to[i]]; } } void dfs1(int u,int father){ for(int i=head[u];i;i=nex[i]){ if(to[i]==father) continue; dfs1(to[i],u);
vector<pii>buf; for(int j=head[to[i]];j;j=nex[j]){ if(to[j]==u) continue; buf.emplace_back(ehsh[j],2*siz[to[j]]); } sort(buf.begin(),buf.end()); ehsh[i]=1; for(pii x:buf) ehsh[i]=(1ll*ehsh[i]*pw[x.second]+x.first)%hshmod; ehsh[i]=(1ll*ehsh[i]*pw[1]+2)%hshmod; } } void dfs2(int u,int father,int rt){ vector<pii>buf; for(int i=head[u];i;i=nex[i]) { if(to[i]==father) buf.emplace_back(ehsh[i],2*(siz[rt]-siz[u])); else buf.emplace_back(ehsh[i],2*siz[to[i]]); } sort(buf.begin(),buf.end()); hsh[u]=1; for(pii x:buf) hsh[u]=(1ll*hsh[u]*pw[x.second]+x.first)%hshmod; hsh[u]=(1ll*hsh[u]*pw[1]+2)%hshmod;
vector<pii>pre(buf),suf(buf); int sz=suf.size(); for(int i=1,j=sz-2;i<sz;i++,j--){ pre[i].first=(1ll*pre[i-1].first*pw[pre[i].second]+pre[i].first)%hshmod; suf[j].first=(1ll*suf[j].first*pw[suf[j+1].second]+suf[j+1].first)%hshmod; pre[i].second+=pre[i-1].second; suf[j].second+=suf[j+1].second; }
for(int i=head[u];i;i=nex[i]){ if(father==to[i]) continue; ehsh[i^1]=1; int idx=lower_bound(buf.begin(),buf.end(),pii(ehsh[i],2*siz[to[i]]))-buf.begin(); if(idx-1>=0) ehsh[i^1]=(1ll*ehsh[i^1]*pw[pre[idx-1].second]+pre[idx-1].first)%hshmod; if(idx+1<sz) ehsh[i^1]=(1ll*ehsh[i^1]*pw[suf[idx+1].second]+suf[idx+1].first)%hshmod; ehsh[i^1]=(1ll*ehsh[i^1]*pw[1]+2)%hshmod; dfs2(to[i],u,rt); } } void treehash(int u,int*hsh_,int*ehsh_,int base,int hshmod_){ hsh=hsh_,ehsh=ehsh_,hshmod=hshmod_; dfs(u,0); for(int i=1;i<=siz[u]*2;i++) pw[i]=1ll*pw[i-1]*base%hshmod; dfs1(u,0),dfs2(u,0,u); }
|