luogu3203 弹飞绵羊 (LCT)
新建一个N+1的点,飞出去的连到这个上,记size,每次统计x和N+1的链长就可以。
别忘了编号是从0开始的
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<map> 7 #include<cmath> 8 #include<ctime> 9 #include<set> 10 #define pa pair<int,int> 11 #define lowb(x) ((x)&(-(x))) 12 #define REP(i,n0,n) for(i=n0;i<=n;i++) 13 #define PER(i,n0,n) for(i=n;i>=n0;i--) 14 #define MAX(a,b) ((a>b)?a:b) 15 #define MIN(a,b) ((a<b)?a:b) 16 #define CLR(a,x) memset(a,x,sizeof(a)) 17 #define rei register int 18 #define lt ch[x][0] 19 #define rt ch[x][1] 20 using namespace std; 21 const int maxn=200020; 22 typedef long long ll; 23 24 ll rd(){ 25 ll x=0;char c=getchar();int neg=1; 26 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 27 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 28 return x*neg; 29 } 30 31 int N,M; 32 int fa[maxn],ch[maxn][2],siz[maxn],to[maxn]; 33 bool rev[maxn]; 34 35 inline void update(int x){siz[x]=(lt?siz[lt]:0)+(rt?siz[rt]:0)+1;} 36 inline void pushrev(int x){ 37 rev[x]^=1;swap(lt,rt); 38 } 39 inline void pushdown(int x){ 40 if(!rev[x]) return; 41 if(lt) pushrev(lt); 42 if(rt) pushrev(rt); 43 rev[x]=0; 44 } 45 inline bool isRoot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 46 inline bool isRson(int x){return x==ch[fa[x]][1];} 47 inline void rotate(int x){ 48 int f=fa[x],ff=fa[f];bool b=isRson(x); 49 if(!isRoot(f)) ch[ff][isRson(f)]=x;fa[x]=ff; 50 if(ch[x][b^1]) fa[ch[x][b^1]]=f;ch[f][b]=ch[x][b^1]; 51 ch[x][b^1]=f;fa[f]=x;update(f);update(x); 52 } 53 inline void pushdall(int x){ 54 if(!isRoot(x)) pushdall(fa[x]);pushdown(x); 55 } 56 inline void splay(int x){ 57 pushdall(x); 58 while(!isRoot(x)&&!isRoot(fa[x])){ 59 if(isRson(x)==isRson(fa[x])) rotate(fa[x]); 60 else rotate(x);rotate(x); 61 }if(!isRoot(x)) rotate(x); 62 } 63 inline void access(int x){ 64 for(int y=0;x;y=x,x=fa[x]){ 65 splay(x);rt=y;update(x); 66 } 67 } 68 inline void setRoot(int x){ 69 access(x);splay(x); 70 pushrev(x); 71 } 72 inline int getRoot(int x){ 73 access(x);splay(x); 74 while(lt){ 75 pushdown(x);x=lt; 76 }return x; 77 } 78 inline void link(int x,int y){//x->y 79 setRoot(x); 80 access(y);splay(y);fa[x]=y; 81 } 82 inline void cut(int x,int y){ 83 setRoot(x);access(y);splay(y); 84 ch[y][0]=fa[x]=0;update(y); 85 } 86 inline int query(int x,int y){ 87 setRoot(x); 88 access(y);splay(y); 89 //printf("%d %d\n",ch[y][0],ch[y][1]); 90 return siz[y]; 91 } 92 inline void change(int x,int k){ 93 if(x+k>N&&x+to[x]>N) return; 94 if(to[x]) cut(x,MIN(x+to[x],N+1)); 95 link(x,MIN(x+k,N+1)); 96 to[x]=k; 97 } 98 99 int main(){ 100 //freopen("3203.in","r",stdin); 101 rei i,j,k;N=rd(); 102 REP(i,1,N) change(i,rd()),siz[i]=1;siz[N+1]=1; 103 M=rd();REP(i,1,M){ 104 j=rd(),k=rd()+1; 105 if(j==1) printf("%d\n",query(N+1,k)-1); 106 else change(k,rd()); 107 } 108 return 0; 109 }