貌似有很多做法。。
LCT打的第一题就是这个,年代久远了。。
从后往前走的话这肯定是一颗树嘛。。查询就是查深度嘛。。修改就是断开一条边连到另一颗树上去嘛。。
以前的巨丑无比的代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=200005,MAX=999999999;
int c[maxn][3],pre[maxn],num[maxn],size[maxn],isroot[maxn],i,n,m,cc,a,b;
void update(int x) {size[x]=size[c[x][0]]+size[c[x][1]]+1;}
void rotate(int x,int kind)
{int y=pre[x],z=pre[y];
int t=size[x];
size[x]=size[y];
size[y]=size[y]-t+size[c[x][kind]];
pre[y]=x;
c[y][!kind]=c[x][kind];
pre[c[x][kind]]=y;
c[x][kind]=y;
pre[x]=z;
if (z&&!isroot[y]) c[z][c[z][1]==y]=x;
if (isroot[y])
{isroot[y]=0;
isroot[x]=1;
}
}
void splay(int x)
{while (!isroot[x] )
{if (isroot[pre[x]]) rotate(x,c[pre[x]][0]==x);
else
{int y=pre[x],kind=c[pre[y]][0]==y;
if (c[y][kind]!=x)
{rotate(y,kind);
rotate(x,kind);
}
else
{rotate(x,!kind);
rotate(x,kind);
}
}
}
}
void print(int x)
{if (x==0) return;
printf("/%d %d %d %d %d %d %d\n",x,num[x],size[x],pre[x],c[x][0],c[x][1],isroot[x]);
print(c[x][0]);
print(c[x][1]);
}
void access(int x)
{splay(x);
if (c[x][1]) isroot[c[x][1]]=1;
c[x][1]=0;
update(x);
int u;
while (pre[x])
{u=pre[x];
splay(u);
if (c[u][1]) isroot[c[u][1]]=1;
c[u][1]=x;
isroot[x]=0;
update(u);
update(x);
splay(x);
//print(x);
}
//print(x);
}
void cut(int x)
{access(x);
splay(x);
if (c[x][0])
{pre[c[x][0]]=pre[x];
isroot[c[x][0]]=1;
}
c[x][0]=0;
pre[x]=0;
update(x);
}
void join(int y,int x)
{if (y>n) y=n+1;
pre[x]=y;
access(x);
}
int main()
{freopen("sheep.in","r",stdin);
freopen("my.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++)
{scanf("%d",&num[i]);
// cout<<"**";
size[i]=1;
pre[i]=i+num[i];
c[i][0]=c[i][1]=0;
isroot[i]=1;
if (pre[i]>n) pre[i]=n+1;
}
c[n+1][0]=c[n+1][1]=0;size[n+1]=1;isroot[n+1]=1;pre[n+1]=0;size[0]=0;
scanf("%d",&m);
for (i=1;i<=m;i++)
{scanf("%d",&cc);
if (cc==1)
{scanf("%d",&a);
access(a+1);
splay(a+1);
//print(a);
printf("%d\n",size[a+1]-size[c[a+1][1]]-1);
}
else
{scanf("%d%d",&a,&b);
if (b==num[a+1]) continue;
num[a+1]=b;
cut(a+1);
join(a+1+num[a+1],a+1);
// for (int j=1;j<=n+1;j++)
// printf("/%d %d %d %d %d %d %d\n",j,num[j],size[j],pre[j],c[j][0],c[j][1],isroot[j]);
}
}
fclose(stdin);
fclose(stdout);
}