| 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
 
 | const int maxn=1e5+5;int to[maxn<<1],nex[maxn<<1],head[maxn],w[maxn],cnt;
 void ini(){cnt=-1;for(int i=0;i<=n;i++) head[i]=-1;}
 void add_edge(int u,int v){to[++cnt]=v;nex[cnt]=head[u];head[u]=cnt;}
 
 int dep[maxn],dad[maxn],siz[maxn],son[maxn],chain[maxn],dfn[maxn];
 void dfs1(int u,int father){
 dep[u]=dep[father]+1;
 dad[u]=father, siz[u]=1, son[u]=-1;
 for(int i=head[u];~i;i=nex[i]){
 int v=to[i];
 if(v==father)continue;
 dfs1(v,u);
 siz[u]+=siz[v];
 if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v;
 }
 }
 void dfs2(int u,int s,int&step){
 dfn[u]=++step;
 chain[u]=s;
 if(son[u]!=-1) dfs2(son[u],s,step);
 for(int i=head[u];~i;i=nex[i]){
 int v=to[i];
 if(v!=son[u]&&v!=dad[u]) dfs2(v,v,step);
 }
 }
 int query(int x,int y,int k){
 int res=0;
 while(chain[x]!=chain[y]){
 if(dep[chain[x]]<dep[chain[y]]) swap(x,y);
 res+=segtree::query(dfn[chain[x]],dfn[x],k);
 x=dad[chain[x]];
 }
 if(dep[x]>dep[y]) swap(x,y);
 return res+segtree::query(dfn[x],dfn[y],k);
 }
 
 |