HDU6394(LCT)
类似于弹飞绵羊的做法 我们对于当前节点往上能达到的节点连边 查询的话直接查询这个点到根的距离即可(只涉及cut和Link的LCT)
#include <algorithm> #include <iostream> #include <vector> const int MAXN=1e5+10; #define ll long long using namespace std; vector<int>vec[MAXN]; struct FastIO { static const int S=200; int wpos; char wbuf[S]; FastIO():wpos(0){} inline int xchar() { static char buf[S]; static int len=0,pos=0; if(pos==len) pos=0,len=fread(buf,1,S,stdin); if(pos==len) exit(0); return buf[pos++]; } inline int read() { int s=1,c=xchar(),x=0; while(c<=32) c=xchar(); if(c=='-') s=-1,c=xchar(); for(;'0'<=c&&c<='9';c=xchar()) x=x*10+c-'0'; return x*s; } ~FastIO() { if(wpos) fwrite(wbuf,1,wpos,stdout),wpos=0; } }io; bool rt[MAXN];int ch[MAXN][2],size[MAXN],pre[MAXN],fa[MAXN][21],n,a[MAXN]; int dep[MAXN]; void dfs(int v,int f,int deep){ fa[v][0]=f;dep[v]=deep+1; for(int i=0;i<vec[v].size();i++){ if(vec[v][i]!=f){ dfs(vec[v][i],v,deep+1); } } } void dfs1(int v){ for(int i=1;i<=20;i++)fa[v][i]=fa[fa[v][i-1]][i-1]; for(int i=0;i<vec[v].size();i++)if(vec[v][i]!=fa[v][0])dfs1(vec[v][i]); } int Lca(int v,int k){ for(int i=0;i<=20;i++)if((k&(1<<i)))v=fa[v][i]; return v; } void P(int r){ if(!rt[r]) P(pre[r]);//传标记 } void up(int x){ size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void rotate(int x,int kind){ int y=pre[x]; ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(rt[y]) rt[y]=false,rt[x]=true; else ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y];ch[x][kind]=y;pre[y]=x; up(y); } void splay(int x){ //P(x); while(!rt[x]){ if(rt[pre[x]]) rotate(x,ch[pre[x]][0]==x); else{ int y=pre[x]; int kind=(ch[pre[y]][0]==y); if(ch[y][kind]==x){ rotate(x,!kind);rotate(x,kind); } else{ rotate(y,kind);rotate(x,kind); } } } up(x); } int access(int u){ int y=0;int x=u; while(u){ splay(u); if(ch[u][1]) rt[ch[u][1]]=1,pre[ch[u][1]]=u,ch[u][1]=0; ch[u][1]=y;pre[y]=u; up(u); if(y) rt[y]=false; up(u); y=u;u=pre[u]; } splay(x); return size[ch[x][0]]+1; } void Cut(int u,int v){ splay(u); if(ch[u][0]) pre[ch[u][0]]=pre[u],rt[ch[u][0]]=1,ch[u][0]=0; up(u); pre[u]=v; } int main(){ int _=io.read(); while(_--){ n=io.read(); int u,v; for(int i=1;i<n;i++)u=io.read(),vec[u].push_back(i+1); dfs(1,0,0);dfs1(1); for(int i=1;i<=n;i++){ a[i]=io.read(); rt[i]=1;ch[i][0]=ch[i][1]=0;size[i]=1; } for(int i=1;i<=n;i++){ if(dep[i]-a[i]>=0) pre[i]=Lca(i,a[i]); else pre[i]=0; } int m;m=io.read(); int op,t1,t2; for(int i=1;i<=m;i++){ op=io.read(); if(op==1) t1=io.read(),printf("%d\n",access(t1)); else{ t1=io.read();t2=io.read(); if(dep[t1]-t2>=0) Cut(t1,Lca(t1,t2)); else Cut(t1,0); } } for(int i=1;i<=n;i++)vec[i].clear(); } return 0; }