zoukankan      html  css  js  c++  java
  • 【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法

    ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,,

    好吧在这道题里我们要弹飞绵羊,有分块和lct两种方法。

    分块:

    #include<cmath>
    #include<cstdio>
    #define for1(i,a,n) for(int i=(a);i<=(n);i++)
    #define for3(i,a,n) for(int i=(a);i>=(n);i--)
    #define read(x) x=getint()
    using namespace std;
    inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
    const int N=200003;
    int n,o[N],t[N],w[N],step[N];
    inline void work(int i){
    	int j=i+t[i];
    	if (j>n) w[i]=n+1,step[i]=1;
    	if (o[i]==o[j]){
    		w[i]=w[j];
    		step[i]=step[j]+1;
    	}else{
    		w[i]=j;
    		step[i]=1;
    	}
    }
    int main(){
    	read(n);
    	for1(i,1,n) read(t[i]);
    	int pn=floor(sqrt(n)),q,id,x,y;
    	for1(i,1,n) o[i]=(i-1)/pn+1;
    	for3(i,n,1) work(i);
    	read(q);
    	while (q--){
    		read(id);
    		if (id==1){
    			read(x); x++; y=0;
    			while (x<=n){
    				y+=step[x];
    				x=w[x];
    			}
    			printf("%d
    ",y);
    		}else{
    			read(x); read(y); x++;
    			t[x]=y;
    			for3(i,x,1)
    				if (o[x]==o[i]) work(i);
    				else break;
    		}
    	}
    	return 0;
    }
    

    LCT(为什么我的lct的常数辣么大T_T)

    #include<cstdio>
    #include<algorithm>
    #define for1(i,a,n) for(int i=(a);i<=(n);i++)
    #define read(x) x=getint()
    using namespace std;
    inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;}
    const int N=200003;
    struct node *null;
    struct node{
    	node();
    	node *fa,*ch[2];
    	int s;
    	void count() {s=1+ch[0]->s+ch[1]->s;}
    	bool pl() {return fa->ch[1]==this;}
    	void setc(node *r,bool c) {ch[c]=r; r->fa=this;}
    	bool check() {return fa==null||((fa->ch[0]!=this)&&(fa->ch[1]!=this));}
    }*rt[N];
    node::node(){s=1;fa=ch[0]=ch[1]=null;}
    int n;
    inline void Build(){null=new node;null->s=0;null->ch[0]=null->ch[1]=null->fa=null;}
    inline void rotate(node *r){
    	node *f=r->fa; bool c=r->pl();
    	if (f->check()) r->fa=f->fa;
    	else f->fa->setc(r,f->pl());
    	f->setc(r->ch[c^1],c);
    	r->setc(f,c^1);
    	f->count(); r->count();
    }
    inline void splay(node *r){
    	for(;!r->check();rotate(r))
    		if (!r->fa->check()) rotate(r->fa->pl()==r->pl()?r->fa:r);
    	r->count();
    }
    inline void access(node *r){
    	for(node *c=null;r!=null;r=r->fa){
    		splay(r);
    		r->setc(c,1);
    		r->count();
    		c=r;
    	}
    }
    inline void link(node *r,node *f){
    	access(r); splay(r);
    	r->ch[0]->fa=null; r->ch[0]=null; r->fa=f; r->count();
    }
    int main(){
    	Build();
    	int t,q,x,y;
    	read(n);
    	for1(i,1,n) rt[i]=new node;
    	for1(i,1,n) {read(t); if (i+t<=n) rt[i]->fa=rt[i+t];}
    	read(q);
    	while (q--){
    		read(x);
    		if (x==1){
    			read(y); y++;
    			access(rt[y]); splay(rt[y]); printf("%d
    ",rt[y]->s);
    		}else{
    			read(x); read(y); x++;
    			if (x+y<=n) link(rt[x],rt[x+y]);
    			else link(rt[x],null);
    		}
    	}
    	return 0;
    }
    

    BeiYu的常数总是比我的要小,,本蒟蒻还得继续努力啊

  • 相关阅读:
    sqoop导入数据到mysql原理_sqoop的详细使用及原理
    Attempt to do update or delete using transaction manager that does not support these operations
    impala安装
    stm32单片机时钟中断的配置
    jtag引脚
    关于芯片封装类型
    Altium Designer绘制mark点
    Altium Designer如何移动选中的所有对象
    Altium Designer敷铜的规则设定
    关于Altium Designer重新修改某一原件pcb封装的问题
  • 原文地址:https://www.cnblogs.com/abclzr/p/5259684.html
Copyright © 2011-2022 走看看