真搞不懂那些写树剖的人,放着60行的树上差分不写,写120左右树剖- -
树剖写的常数大还会T。。。差分稳如狗啊。
#include<bits/stdc++.h> using namespace std; const int maxn=300010; int a[maxn],cnt=0,head[maxn],root=1,f[maxn][25],dep[maxn],cha[maxn]; struct edge{ int to,next; }e[maxn*2]; void add_edge(int s,int t){ e[++cnt].next=head[s];e[cnt].to=t;head[s]=cnt; e[++cnt].next=head[t];e[cnt].to=s;head[t]=cnt; } void dfs(int u){ for(int i=head[u];i;i=e[i].next){ if(!dep[e[i].to]){ dep[e[i].to]=dep[u]+1; f[e[i].to][0]=u; dfs(e[i].to); } } } void dfs2(int u){ for(int i=head[u];i;i=e[i].next){ if(dep[e[i].to]>dep[u]){ dfs2(e[i].to); cha[u]+=cha[e[i].to]; } } } int lca(int a,int b){ if(dep[a]<dep[b])swap(a,b); for(int i=0;i<25;++i){ if(((dep[a]-dep[b])>>i)&1)a=f[a][i]; } if(a==b)return a; for(int i=24;i>=0;--i){ if(f[a][i]!=f[b][i]){ a=f[a][i];b=f[b][i]; } } return f[a][0]; } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%d",&a[i]); for(int i=1;i<=n-1;++i){ int s,t; scanf("%d%d",&s,&t); add_edge(s,t); } dep[root]=1; dfs(root); for(int j=1;j<25;++j){ for(int i=1;i<=n;++i){ if(f[i][j-1])f[i][j]=f[f[i][j-1]][j-1]; } } for(int i=1;i<n;++i){ int l=lca(a[i],a[i+1]); cha[a[i]]++;cha[a[i+1]]++;cha[l]--;cha[f[l][0]]--; } dfs2(root); for(int i=2;i<=n;++i)cha[a[i]]--; for(int i=1;i<=n;++i)printf("%d\n",cha[i]); return 0; }