| 12
 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);
 }
 
 
 |