3 条题解

  • 0
    @ 2026-7-28 0:25:05
    //分块解法
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define MaxN 200500
    using namespace std;
    int BS,t[MaxN],b[MaxN],c[MaxN];
    void build(int p)
    {
      int l=p*BS,r=l+BS;
      for (int i=r-1;i>=l;i--)
        if (t[i]>=r){b[i]=t[i];c[i]=1;}
        else {b[i]=b[t[i]];c[i]=c[t[i]]+1;}
    }
    int n,m,nn;
    int qry(int p)
    {
      int ret=0;
      while(p<n){ret+=c[p];p=b[p];}
      return ret;
    }
    int main()
    {
      scanf("%d",&n);
      BS=sqrt(n)+1;
      nn=(n-1)/BS*BS+BS;
      for (int i=0;i<n;i++){
        scanf("%d",&t[i]);
        t[i]+=i;if (t[i]>=n)t[i]=nn;
      }for (int i=n;i<m;i++)t[i]=nn;
      for (int i=0;i<nn/BS;i++)build(i);
      scanf("%d",&m);
      for (int i=0,op,p,x;i<m;i++){
        scanf("%d%d",&op,&p);
        if (op==2){
          scanf("%d",&t[p]);
          t[p]+=p;if (t[p]>=n)t[p]=nn;
          build(p/BS);
        }else printf("%d\n",qry(p));
      }return 0;
    }
    
    • 0
      @ 2026-1-12 17:55:21

      #include <bits/stdc++.h>
      #define N 256101
      using namespace std;
      
      int n, q, op, i;
      int nxt[N];
      
      namespace LCT{
      	#define pa p[nd]
      
      	struct node {int sz, rev, c[2], p;} nd[N];
      
      	inline int dir(int x) {return !x[nd].p ? -1 : x == x[nd].pa.c[0] ? 0 : x == x[nd].pa.c[1] ? 1 : -1;}
      
      	void reverse(int x) {swap(x[nd].c[0], x[nd].c[1]); x[nd].rev ^= 1;}
      
      	void push_down(int x) {if(x[nd].rev) {reverse(x[nd].c[0]); reverse(x[nd].c[1]); x[nd].rev = 0;} }
      
      	void pull_down(int x) {if(~dir(x)) pull_down(x[nd].p); push_down(x);}
      
      	inline void update(int x) {nd[x].sz = nd[x].c[0][nd].sz + nd[x].c[1][nd].sz + 1;}
      
      	void rotate(int x){
      		int y = x[nd].p, d = !dir(x);
      		nd[y[nd].c[!d] = x[nd].c[d]].p = y;
      		x[nd].p = y[nd].p;
      		if(~dir(y)) y[nd].pa.c[dir(y)] = x;
      		nd[x[nd].c[d] = y].p = x;
      		update(y);
      	}
      
      	void splay(int x){
      		for(pull_down(x); ~dir(x); rotate(x))
      			if(~dir(x[nd].p)) rotate(dir(x) ^ dir(x[nd].p) ? x : x[nd].p);
      		update(x);
      	}
      
      	void access(int x) {for(int y = 0; x; y = x, x = x[nd].p){
      		splay(x); x[nd].c[1] = y; update(x);}}
      
      	void make_root(int x) {access(x); splay(x); reverse(x);}
      
      	int find_root(int x) {access(x); splay(x); for(; x[nd].c[0]; x = x[nd].c[0]); return x;}
      
      	void link(int x, int y) {make_root(x); x[nd].p = y;}
      
      	void split(int x, int y) {make_root(x); access(y); splay(y);}
      
      	void cut(int x, int y) {split(x, y); x[nd].p = y[nd].c[0] = 0; update(y);}
      }
      
      int main(){
      	scanf("%d", &n);
      	for(i = 1; i <= n; ++i){
      		scanf("%d", nxt + i); nxt[i] += i;
      		LCT::link(i, nxt[i] > n ? n + 1 : nxt[i]);
      	}
      	for(scanf("%d", &q); q; --q)
      		if(scanf("%d%d", &op, &i), ++i, op == 1){
      			LCT::split(n + 1, i);
      			printf("%d\n", LCT::nd[i].sz - 1);
      		}else{
      			LCT::cut(i, nxt[i] > n ? n + 1 : nxt[i]);
      			scanf("%d", nxt + i); nxt[i] += i;
      			LCT::link(i, nxt[i] > n ? n + 1: nxt[i]);
      		}
      	return 0;
      }
      
      
      • 0
        @ 2026-1-11 11:39:31

        极简 LCT:

        #include<bits/stdc++.h>
        using namespace std;
        #define lc(p) tr[p].ch[0]
        #define rc(p) tr[p].ch[1]
        #define fa(p) tr[p].f
        const int N=3e5+10;
        struct node{int ch[2],f,v,s,tag;}tr[N];
        bool notrt(int x){return lc(fa(x))==x||rc(fa(x))==x;}
        void pushup(int p){tr[p].s=tr[lc(p)].s+tr[rc(p)].s+1;}
        void rotate(int x)
        {
        	int y=fa(x),z=fa(y),k=rc(y)==x;
        	if(notrt(y))tr[z].ch[rc(z)==y]=x;fa(x)=z;
        	tr[y].ch[k]=tr[x].ch[k^1];fa(tr[x].ch[k^1])=y;
        	tr[x].ch[k^1]=y;fa(y)=x;
        	pushup(y);pushup(x);
        }
        void splay(int x)
        {
        	while(notrt(x))
        	{
        		int y=fa(x),z=fa(y);
        		if(notrt(y))((rc(y)==x)^(rc(z)==y))?rotate(x):rotate(y);
        		rotate(x);
        	}
        	pushup(x);
        }
        void access(int x)
        {
        	for(int y=0;x;)
        	{
        		splay(x);
        		rc(x)=y;
        		pushup(x);
        		y=x;x=fa(x);
        	}
        }
        int main()
        {
        	int n,q;cin>>n;
        	for(int i=1;i<=n;i++)
        	{
        		int x;cin>>x;
        		tr[i].s=1;
        		if(i+x<=n)fa(i)=i+x;
        	}
        	cin>>q;
        	while(q--)
        	{
        		int op,x,y;cin>>op;
        		if(op==1)
        		{
        			cin>>x;x++;
        			access(x),splay(x);
        			cout<<tr[x].s<<'\n';
        		}
        		else 
        		{
        			cin>>x>>y;x++;
        			access(x);splay(x);
        			lc(x)=fa(lc(x))=0;
        			fa(x)=(x+y<=n?x+y:0);
        			pushup(x);
        		}
        	}
        	return 0;
        }
        
        • 1

        【动态树 LCT】[HNOI2010] 弹飞绵羊

        信息

        ID
        3667
        时间
        1000ms
        内存
        128MiB
        难度
        9
        标签
        递交数
        10
        已通过
        7
        上传者