您的位置:首页 > 其它

Link-Cut Tree指针模板

2017-12-15 12:59 816 查看

模板:

  以下为弹飞绵羊代码:

#define Troy

#include "bits/stdc++.h"

using namespace std;

const int N=2e5+5;

inline int read(){
int s=0,k=1;char ch=getchar();
while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
return s*k;
}

#define size(t) (t?t->size:0)
#define rev(t)  (t?t->rev^=1:0)

struct Node{
int size,rev;
Node *fa,*son[2];
Node(){fa=son[0]=son[1]=NULL;size=1,rev=0;}
inline void update(){
size=1+size(son[0])+size(son[1]);
}
inline void pushdown(){
if(!rev)    return;
rev=0,swap(son[0],son[1]);
rev(son[0]),rev(son[1]);
}
}*pool
,*tmp
,tree
;int top;

inline void init_pool(){for(;top<N;++top)   pool[top]=tree+top;}

inline void newNode(Node *&p,Node *f){p=pool[--top];*p=Node();p->fa=f;}
inline void freeNode(Node *&p){pool[top++]=p,p=NULL;}

int to
,n;
class LinkCutTree{
public:
Node *node
;
inline void init(int n){for(register int i=1;i<=n;++i)newNode(node[i],NULL);}

#define son(p)  (p->fa->son[1]==p)
#define is_root(p)  ((!p->fa)||(p->fa->son[0]!=p&&p->fa->son[1]!=p))

inline void rotate(Node *p){
int a=son(p)^1;Node *f=p->fa;
f->son[a^1]=p->son[a];
if(p->son[a])   p->son[a]->fa=f;
p->fa=f->fa;
if(!is_root(f))   p->fa->son[son(f)]=p;
f->fa=p,p->son[a]=f,f->update(),p->update();
}

inline void splay(Node *p){
register int pos=0;
for(Node *t=p;;t=t->fa){
tmp[++pos]=t;
if(is_root(t)) break;
}
for(;pos;--pos) tmp[pos]->pushdown();
for(;!is_root(p);rotate(p))
if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
}

inline void access(Node *p){
for(Node *pre=NULL;p;pre=p,p=p->fa)
splay(p),p->son[1]=pre,p->update();
}

inline void make_root(Node *p){
access(p),splay(p),rev(p);
}

inline void cut(Node *x,Node *y){
make_root(x),access(y),splay(y);
x->fa=y->son[0]=NULL;y->update();
}

inline void link(Node *x,Node *y){make_root(x);x->fa=y;}
inline void link(int x,int y){node[x]->fa=node[y];}

inline void op1(int x){
make_root(node[n+1]),access(node[x]),splay(node[x]);
printf("%d\n",node[x]->size-1);
}

inline void op2(int x,int y){
cut(node[x],node[min(n+1,x+to[x])]);
link(node[x],node[min(n+1,y+x)]);to[x]=y;
}
}lct;

int main(){
n=read();
init_pool();
lct.init(n+1);
register int i;
for(i=1;i<=n;++i){
to[i]=read();
lct.link(i,min(i+to[i],n+1));
}
int q=read(),x,y;
while(q--){
if(read()==1)
lct.op1(read()+1);
else{
x=read(),y=read();
lct.op2(x+1,y);
}
}return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: