2016-05-30 11:51:59

用一个next数组,记录点x的下一个点是哪个

查询时,moveroot(n+1),access(x),splay(x) ,输出size[ch[x][0]]即为答案

更改时,cut(x,next[x]) link(x,min(x+k,n+1))

记得splay旋转后要更新size

 1 #include<bits/stdc++.h>
 2 #define N 200005
 3 using namespace std;
 4 int read(){
 5   int x=0,f=1;char ch=getchar();
 6   while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7   while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 8   return x*f;
 9 }
10 int n,m,next[N];
11 namespace LCT{
12   int ch[N][2],fa[N],sz[N];bool rev[N];
13   inline bool isroot(int x){
14     if(ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x)return 1;return 0;
15   }
16   inline void pushdown(int x){
17     if(rev[x]){
18       rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]=0;
19       swap(ch[x][0],ch[x][1]);
20     }
21   }
22   inline void pushup(int x){
23     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
24   }
25   void rotate(int x){
26     int y=fa[x],k=ch[y][1]==x;
27     if(!isroot(y))ch[fa[y]][ch[fa[y]][1]==y]=x;
28     fa[x]=fa[y];
29     fa[ch[x][!k]]=y;
30     fa[y]=x;
31     ch[y][k]=ch[x][!k];
32     ch[x][!k]=y;
33     pushup(y);pushup(x);
34   }
35   void Pushdown(int x){
36     if(!isroot(x))Pushdown(fa[x]);
37     pushdown(x);
38   }
39   void splay(int x){
40       Pushdown(x);
41       for(int y=fa[x];!isroot(x);y=fa[x]){
42         if(!isroot(y)){
43             if((ch[fa[y]][ch[fa[y]][1]==y])!=(ch[y][1]==x))rotate(x);
44             else rotate(y);
45         }rotate(x);
46     }
47   }
48   inline void access(int x){
49     int y=0;
50     while(x){
51       splay(x);
52       ch[x][1]=y;
53       x=fa[y=x];
54     }
55   }
56   inline void moveroot(int x){
57     access(x);splay(x);rev[x]^=1;
58   }
59   inline void link(int x,int y){
60       moveroot(x);fa[x]=y;splay(x);
61   }
62   inline void cut(int x,int y){
63       moveroot(x);access(y);splay(y);ch[y][0]=fa[x]=0;
64   }
65   inline int query(int x){
66       moveroot(n+1);access(x);splay(x);
67       return sz[ch[x][0]];
68   }
69 }
70 int main(){
71   n=read();
72   for(int i=1;i<=n;i++){
73     int x=read();
74     LCT::fa[i]=x+i;LCT::sz[i]=1;
75     if(LCT::fa[i]>n)LCT::fa[i]=n+1;
76     next[i]=LCT::fa[i];
77   }
78   m=read();
79   while(m--){
80     int t=read();
81     if(t==1)printf("%d\n",LCT::query(read()+1));
82     else {
83       int x=read(),y=read();x++;
84       int t=min(n+1,x+y);
85       LCT::cut(x,next[x]);LCT::link(x,t);next[x]=t;
86     }
87   }
88   return 0;
89 }
View Code

相关文章:

  • 2021-06-24
  • 2021-05-22
  • 2022-12-23
  • 2021-05-24
  • 2022-02-09
  • 2021-09-12
  • 2021-09-02
猜你喜欢
  • 2021-10-14
  • 2021-09-14
  • 2021-11-24
  • 2021-07-12
  • 2021-09-21
  • 2021-05-19
相关资源
相似解决方案