您的位置:首页 > 其它

[BZOJ2002] [HNOI2010] 弹飞绵羊 - Link-Cut-Tree (LCT)

2016-06-07 16:25 429 查看
        LCT绝对的模板题啊(黄学长一开始用分块写的感觉很高端啊%%%

        呐……LCT写起来也是很简单的啊……根本不用维护一些其他的东西,只要最基本的操作。询问都不用别的直接makeroot然后access然后splay就好……

        好吧具体看代码。建议在最后加一个点n+1(感觉不加我就不会写。

#include "algorithm"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "vector"
#include "math.h"
#include "map"
#include "set"

#define rep(f,a,b) for(f=a;f<=b;f++)

using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}

struct node {
node *fa,*c[2];
int size;
bool rev;
node ();
void push_up();
void push_down();
} Tnull,*null=&Tnull;

const int N=200005;
int n,a
,q; node v
;

node :: node(){
fa=c[0]=c[1]=null;
size=0; rev=false;
}

void node :: push_up(){
size=c[0]->size+c[1]->size+1;
}

void node :: push_down(){
if (fa->c[0]==this || fa->c[1]==this)
fa->push_down();
if(rev){
c[0]->rev^=1;
c[1]->rev^=1;
swap(c[0],c[1]);
rev=false;
}
}

inline bool isroot (node *x){
return x->fa->c[0]!=x && x->fa->c[1]!=x;
}

void rotate (node *x){
node *y=x->fa,*z=y->fa;
if (z!=null){
if(z->c[0]==y) z->c[0]=x;
if(z->c[1]==y) z->c[1]=x;
}
int l=y->c[1]==x,r=l^1;
if(x->c[r]!=null) x->c[r]->fa=y;
x->fa=z; y->fa=x; y->c[l]=x->c[r];
x->c[r]=y; y->push_up(); x->push_up();
}

void splay (node *x){
x->push_down();
while (isroot(x)^1){
node *y=x->fa,*z=y->fa;
if(isroot(y)^1){
if (z->c[0]==y ^ y->c[0]==x) rotate(x);
else rotate(y);
}
rotate(x);
}
x->push_up();
}

void access (node *x){
for (node *y=null;x!=null;y=x,x=x->fa)
splay(x),x->c[1]=y,x->push_up();
}

void makeroot (node *x){
access(x); splay(x);
x->rev^=1;
}

void link (node *x,node *y){
makeroot(x);
x->fa=y;
}

void cut (node *x,node *y){
makeroot(x); access(y);
splay(y); x->fa=null;
y->c[0]=null; y->push_up();
}

int work (node *x){
makeroot(v+n+1);
access(x); splay(x);
x->push_down();
return x->size-1;
}

int main(){
int i; n=read();
rep(i,1,n){ a[i]=read();
if(i+a[i]<=n)
link(v+i,v+i+a[i]);
else link(v+i,v+n+1);
} v[n+1].size=1;
int type,tot,pos; q=read();
rep(i,1,q){ type=read();
if(type==1){ pos=read(); pos++;
printf("%d\n",work(v+pos));}
else { pos=read(); tot=read(); pos++;
if(pos+a[pos]<=n)cut(v+pos,v+pos+a[pos]); else cut(v+pos,v+n+1);
if(pos+tot<=n)link(v+pos,v+pos+(a[pos]=tot));
else link(v+pos,v+n+1),a[pos]=tot;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: