标签:
LCT=树链剖分+平衡树(多用Splay),AC之后才对这个等式深有感触……
我们定义一个操作Access(x),这个操作可以将从x到根节点路径上的所有节点放到一颗Splay里,一切操作都在这棵Splay里做。你说要维护任意两个点的路径?反正是无向树换一下根不就好了……
我们以执行Access的顺序为权值来进行树链剖分,每一条链用一颗Splay按照深度来维护,每一颗Splay与他的父亲(由于一条链一定是在一个点u的子树上,所以我们只需要让这颗Splay的根与u相连就好,无所谓根和u在原树中是否相连)用一条单向边(儿子指向父亲但父亲不指向儿子)相连。也就是说:
对于任意一个点,除他的 重儿子/偏爱儿子 用双向边相连外,轻儿子/非偏爱儿子 均用单向边相连。
(LCT中重儿子称为偏爱儿子,重链称为偏爱路径,重边称为偏爱边)
Access的时候不断向上更新拆Splay然后重新建树即可,具体参见PoPoqqq神犇的课件,在此Orz
——————————————————————————————————————————————————————————————————————————————
本题细节上的问题:标号是从0到n-1
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=200000+2;
typedef struct NODE{
int c;
NODE *f,*child[2];
} *TREE;
TREE mark[MAXN],Null;
int N,M;
TREE NewNode(TREE f){
TREE x=new NODE;
x->f=f,x->c=1;
x->child[0]=x->child[1]=Null;
return x;
}
void Initialise(int N){
Null=NewNode(0),Null->c=0;
for(int i=1;i<=N;i++) mark[i]=NewNode(Null);
}
void Pushup(TREE &x){ x->c=x->child[0]->c+x->child[1]->c+1;}
void Rotate(TREE &x,bool t){
TREE y=x->f;
y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f;
if(y->f->child[0]==y) y->f->child[0]=x;
else if(y->f->child[1]==y) y->f->child[1]=x;
y->f=x,x->child[t]=y;
Pushup(y),Pushup(x);
}
void Splay(TREE &x){
while(x->f->child[0]==x || x->f->child[1]==x){
TREE y=x->f;
if(x==y->child[0]){
if(y==y->f->child[0]) Rotate(y,1);
Rotate(x,1);
}
else{
if(y==y->f->child[1]) Rotate(y,0);
Rotate(x,0);
}
}
}
void Access(TREE &x){
TREE y=Null,z=x;
while(x!=Null){
Splay(x);
x->child[1]=y;
Pushup(x);
y=x,x=x->f;
}
x=z;
}
void Link(TREE &x,TREE &y){
Access(x),Splay(x);
x->child[0]->f=Null,x->child[0]=Null;
x->f=y;
Pushup(x);
}
int main(){
cin >> N;
Initialise(N);
for(int i=1,d;i<=N;i++){
cin >> d;
if(i+d<=N) mark[i]->f=mark[i+d];
}
cin >> M;
for(int i=1,a,b,d;i<=M;i++){
cin >> a >> b,b++;
if(a==1){
Access(mark[b]),Splay(mark[b]);
cout << mark[b]->c << endl;
}
else{
cin >> d;
if(b+d<=N) Link(mark[b],mark[b+d]);
else Link(mark[b],Null);
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/wdzrmpcbit/article/details/51335236