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
",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
",query(N+1,k)-1);
106         else change(k,rd());
107     }
108     return 0;
109 }
原文地址:https://www.cnblogs.com/Ressed/p/9603314.html