[BZOJ3631][JLOI2014]松鼠的新家(树链剖分)
树剖模板题了,
Code
#include <cstdio> #include <algorithm> #define MID int mid=(l+r)>>1,ls=id<<1,rs=id<<1|1 #define N 300010 using namespace std; struct info{int to,nex;}e[N*2]; int n,A[N],tot,head[N],tag[N*4],Ans[N]; int dep[N],fa[N],sz[N],son[N]; int cnt,tp[N],rk[N],tid[N]; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void Link(int u,int v){ e[++tot].nex=head[u];e[tot].to=v;head[u]=tot; } inline void pushdown(int l,int r,int id){ MID; tag[ls]+=tag[id]; tag[rs]+=tag[id]; tag[id]=0; } void update(int l,int r,int id,int L,int R){ if(L<=l&&r<=R){ tag[id]++; return; } MID; if(tag[id]) pushdown(l,r,id); if(L<=mid) update(l,mid,ls,L,R); if(R>mid) update(mid+1,r,rs,L,R); } void query(int l,int r,int id){ if(l==r){Ans[rk[l]]=tag[id];return;} if(tag[id]) pushdown(l,r,id); MID; if(l<=mid) query(l,mid,ls); if(r>mid) query(mid+1,r,rs); } void dfs(int u,int pre){ sz[u]=1; for(int i=head[u],mx=0;i;i=e[i].nex){ int v=e[i].to; if(v==pre) continue; dep[v]=dep[u]+1; fa[v]=u; dfs(v,u); sz[u]+=sz[v]; if(sz[v]>mx) son[u]=v,mx=sz[v]; } } void dddfs(int u,int top){ tp[u]=top; tid[u]=++cnt; rk[cnt]=u; if(!son[u]) return; dddfs(son[u],top); for(int i=head[u];i;i=e[i].nex){ int v=e[i].to; if(v!=son[u]&&v!=fa[u]) dddfs(v,v); } } inline void updRange(int u,int v){ while(tp[u]!=tp[v]){ if(dep[tp[u]]<dep[tp[v]]) swap(u,v); update(1,n,1,tid[tp[u]],tid[u]); u=fa[tp[u]]; } if(dep[u]>dep[v]) swap(u,v); update(1,n,1,tid[u],tid[v]); } inline void Init(){ n=read(); for(int i=1;i<=n;A[i++]=read()); for(int i=1;i<n;++i){ int u=read(),v=read(); Link(u,v),Link(v,u); } dfs(1,0); dddfs(1,1); } inline void solve(){ for(int i=1;i<n;++i) updRange(A[i],A[i+1]); query(1,n,1); for(int i=2;i<=n;++i) Ans[A[i]]--; for(int i=1;i<=n;printf("%d\n",Ans[i++])); } int main(){Init();solve();}