BZOJ - 3631 松鼠的新家 (树链剖分)
树链剖分基础题,路径权值修改+差分
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=3e5+10; 5 int hd[N],ne,n,m,a[N],fa[N],son[N],dep[N],siz[N],top[N],dfn[N],rnk[N],tot,c[N]; 6 struct E {int v,nxt;} e[N<<1]; 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} 8 void dfs1(int u,int f,int d) { 9 fa[u]=f,son[u]=0,dep[u]=d,siz[u]=1; 10 for(int i=hd[u]; ~i; i=e[i].nxt) { 11 int v=e[i].v; 12 if(v==fa[u])continue; 13 dfs1(v,u,d+1),siz[u]+=siz[v]; 14 if(siz[v]>siz[son[u]])son[u]=v; 15 } 16 } 17 void dfs2(int u,int tp) { 18 top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u; 19 if(!son[u])return; 20 dfs2(son[u],top[u]); 21 for(int i=hd[u]; ~i; i=e[i].nxt) { 22 int v=e[i].v; 23 if(v==fa[u]||v==son[u])continue; 24 dfs2(v,v); 25 } 26 } 27 void upd(int u,int v) { 28 for(; top[u]!=top[v]; u=fa[top[u]]) { 29 if(dep[top[u]]<dep[top[v]])swap(u,v); 30 c[dfn[top[u]]]++,c[dfn[u]+1]--; 31 } 32 if(dep[u]<dep[v])swap(u,v); 33 c[dfn[v]]++,c[dfn[u]+1]--; 34 } 35 36 int main() { 37 memset(hd,-1,sizeof hd),ne=0; 38 scanf("%d",&n); 39 for(int i=0; i<n; ++i)scanf("%d",&a[i]); 40 for(int i=1; i<n; ++i) { 41 int u,v; 42 scanf("%d%d",&u,&v); 43 addedge(u,v); 44 addedge(v,u); 45 } 46 tot=0,dfs1(1,0,0),dfs2(1,1); 47 for(int i=0; i<n-1; ++i)upd(a[i],a[i+1]); 48 for(int i=1; i<=tot; ++i)c[i]+=c[i-1]; 49 for(int i=1; i<n; ++i)c[dfn[a[i]]]--; 50 for(int i=1; i<=n; ++i)printf("%d\n",c[dfn[i]]); 51 return 0; 52 }