• P3203 [HNOI2010]弹飞绵羊


    题目

    P3203 [HNOI2010]弹飞绵羊

    做法

    本来以为是个水题,其实还是有思维性的

    (LCT)上操作和模板一样,显然我们维护子树大小

    开始是想(Link(x,x+val[x]))(x+val[x]>n)时就不连,然后查询(x)时就查询右子树大小

    反例就不举了随手就是个反例吧反正这种办法是错的

    正解:(Link(x,x+val[x]))(x+val[x]>n)(Link(x,n+1))

    查询(x)时其实就是查询(x)~(n+1)这条链:(Makeroot(x); Access(n+1); Splay(n+1);),输出(size[n+1]-1)

    My complete code

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<stack>
    using namespace std;
    typedef int LL;
    const LL maxn=1e6;
    inline LL Read(){
    	LL x(0),f(1);char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    	return x*f;
    }
    LL n,m;
    LL size[maxn],fa[maxn],son[maxn][2],r[maxn],val[maxn];
    
    inline bool Notroot(LL x){
    	return (son[fa[x]][0]==x||son[fa[x]][1]==x);
    }
    inline void Pushr(LL x){
    	swap(son[x][0],son[x][1]);r[x]^=1;
    }
    inline void Pushdown(LL x){
    	if(r[x]){
    		if(son[x][0])Pushr(son[x][0]);
    		if(son[x][1])Pushr(son[x][1]);
    		r[x]^=1;
    	}
    }
    inline void Update(LL x){
    	size[x]=1+size[son[x][0]]+size[son[x][1]];
    }
    inline void Rotate(LL x){
    	LL y(fa[x]),z(fa[y]),lz=(son[y][1]==x);
    	if(Notroot(y))
    		son[z][son[z][1]==y]=x;
    	fa[x]=z;
    	son[y][lz]=son[x][lz^1];
    	if(son[y][lz])
    	    fa[son[y][lz]]=y;
    	son[x][lz^1]=y;fa[y]=x;
    	Update(y),Update(x);
    }
    LL sta[maxn];
    inline void Splay(LL x){
    	LL y(x),top(0);
    	sta[++top]=y;
    	while(Notroot(y)) sta[++top]=y=fa[y];
    	while(top) Pushdown(sta[top--]);
    	while(Notroot(x)){
    		y=fa[x];
    		if(Notroot(y)){
    			LL z=fa[y];
    			if(((son[z][1]==y)^(son[y][1]==x))==0) Rotate(y);
    			else Rotate(x);
    		}
    		Rotate(x);
    	}
    }
    inline void Access(LL x){
    	for(LL y=0;x;y=x,x=fa[x]){
    		Splay(x),son[x][1]=y;Update(x);
    	}
    }
    inline void Makeroot(LL x){
    	Access(x),Splay(x),Pushr(x);
    }
    inline void Split(LL x,LL y){
    	Makeroot(x),Access(y),Splay(y);
    }
    
    inline void Link(LL x,LL y){
    	Makeroot(y);
    	fa[y]=x;
    }
    inline void Delet(LL x,LL y){
    	Split(x,y);
    	fa[x]=son[y][0]=0;
    	Update(y);
    }
    int main(){
    	n=Read();
    	for(LL i=1;i<=n;++i) size[i]=1;
    	for(LL i=1;i<=n;++i){
    		val[i]=Read();
    		if(i+val[i]<=n)
    		    Link(i,i+val[i]);
    		else
    		    Link(i,n+1);
    	}
    	m=Read();
    	while(m--){
    		LL op(Read());
    		if(op==1){
    			LL x(Read()+1);
    			Makeroot(x); Access(n+1); Splay(n+1);
    			printf("%d
    ",size[n+1]-1);
    		}else{
    			LL x(Read()+1),y(Read());
    			if(x+val[x]<=n) Delet(x,x+val[x]);
    			else Delet(x,n+1);
    			val[x]=y;
    			if(x+val[x]<=n) Link(x,x+val[x]);
    			else Link(x,n+1);
    		}
    	}
    }
    
  • 相关阅读:
    Codeforces 1196E. Connected Component on a Chessboard
    Codeforces 1196C. Robot Breakout
    Codeforces 1194E. Count The Rectangles
    Codeforces 1194D. 1-2-K Game
    Codeforces 1194C. From S To T
    Codeforces 1194B. Yet Another Crosses Problem
    Codeforces 1194A. Remove a Progression
    Codeforces 1201E2. Knightmare (hard)
    关于cookie
    关于js的addEventListener 和一些常用事件
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10323244.html
Copyright © 2020-2023  润新知