[bzoj2002]Bounce 弹飞绵羊
LCT板子题
注意每个点的size可以直接在splay操作的时候维护
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m;
struct SplayNode{
int ch[2],fa;
int sz;
}t[N];
int root;
int null=0;
inline bool isroot(int x){return t[t[x].fa].ch[1]!=x&&t[t[x].fa].ch[0]!=x;}
inline int son(int x){return t[t[x].fa].ch[1]==x;}
inline void init(int p){for(int i=1;i<=p;i++)t[i].sz=1;}
void update(int x){
t[x].sz=1;
if(t[x].ch[0])t[x].sz+=t[t[x].ch[0]].sz;
if(t[x].ch[1])t[x].sz+=t[t[x].ch[1]].sz;
}
inline void rotate(int x){
int f=t[x].fa,gf=t[t[x].fa].fa;
int a=son(x),b=son(x)^1;
if(!isroot(f))t[gf].ch[son(f)]=x;
t[x].fa=gf;
t[f].ch[a]=t[x].ch[b];t[t[x].ch[b]].fa=f;
t[x].ch[b]=f;t[f].fa=x;
update(f);update(x);
}
inline void splay(int x){
while(!isroot(x)){
int f=t[x].fa;
if(!isroot(f)){
if(son(x)^son(f))rotate(x);
else rotate(f);
}
rotate(x);
}
}
void access(int x){
int tmp=null;
do{
splay(x);
t[x].ch[1]=tmp;
update(x);
tmp=x;x=t[x].fa;
}while(x!=null);
}
int NN;
void link(int u,int v){
if(v>NN)v=null;
access(u);
splay(u);
t[t[u].ch[0]].fa=null;
t[u].ch[0]=null;
t[u].fa=v;
update(u);
}
int main()
{
scanf("%d",&n);
NN=n;
root=n+1;
init(n+1);
for(int v,i=1;i<=n;i++){
scanf("%d",&v);
link(i,i+v);
}
scanf("%d",&m);
while(m--){
int opt,v,u;
scanf("%d",&opt);
if(opt==1){
scanf("%d",&u);
access(u+1);
splay(u+1);
printf("%d\n",t[t[u+1].ch[0]].sz+1);
}
else{
scanf("%d%d",&u,&v);
link(u+1,u+1+v);
}
}
}