您的位置:首页 > 其它

LCT(Bounce 弹飞绵羊,BZOJ 2002)

2017-07-21 14:25 555 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002

参考博客:

http://blog.csdn.net/wzq_qwq/article/details/47397539

http://blog.csdn.net/saramanda/article/details/55210418

http://blog.csdn.net/clove_unique/article/details/50991685

pushup函数用于更新Auxiliary Tree中子树的节点个数。

凡是Auxiliary Tree会变化的地方(树形态的变化和树重构的变化)都要更新一下,不过追根溯源,只要在rotate函数,access函数以及update函数中使用这个pushup函数即可。

代码

/**************************************************************
Problem: 2002
User: 2015190026
Language: C++
Result: Accepted
Time:2508 ms
Memory:11064 kb
****************************************************************/

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 200010;

struct node
{
int fa,ch[2];
bool reverse,is_root;
int s;
void init()
{
fa=ch[0]=ch[1]=0;
reverse=0;
is_root=1;
s=1;
}
}T[maxn];

void pushup(int x)
{
T[x].s=T[T[x].ch[0]].s+T[T[x].ch[1]].s+1;
}

int getson(int x)
{
return x==T[T[x].fa].ch[1];
}

void pushreverse(int x)
{
if(!x) return;
swap(T[x].ch[0],T[x].ch[1]);
T[x].reverse^=1;
}

void pushdown(int x)
{
if(T[x].reverse)
{
pushreverse(T[x].ch[0]);
pushreverse(T[x].ch[1]);
T[x].reverse=false;
}
}

void rotate(int x)
{
if(T[x].is_root) return;
int k=getson(x);
int fa=T[x].fa;
int fafa=T[fa].fa;
pushdown(fa);
pushdown(x);
T[fa].ch[k]=T[x].ch[k^1];
if(T[x].ch[k^1]) T[T[x].ch[k^1]].fa=fa;
T[x].ch[k^1]=fa;
T[fa].fa=x;
T[x].fa=fafa;
if(T[fa].is_root)
{
T[fa].is_root=false;
T[x].is_root=true;
}
else
{
T[fafa].ch[fa==T[fafa].ch[1]]=x;
}
pushup(fa);
pushup(x);
}

void push(int x)
{
if(!T[x].is_root) push(T[x].fa);
pushdown(x);
}

void Splay(int x)
{
push(x);
for(int fa;!T[x].is_root;rotate(x))
{
if(!T[fa=T[x].fa].is_root)
{
rotate((getson(x)==getson(fa))?fa:x);
}
}
}

void access(int x)
{
int y=0;
do
{
Splay(x);
T[T[x].ch[1]].is_root=true;
T[T[x].ch[1]=y].is_root=false;
pushup(x);
x=T[y=x].fa;
}while(x);
}

void mroot(int x)
{
access(x);
Splay(x);
pushreverse(x);
}

void link(int u,int v)
{
mroot(u);
T[u].fa=v;
}

void cut(int u,int v)
{
mroot(u);
access(v);
Splay(v);
pushdown(v);
T[T[v].ch[0]].fa=T[v].fa;
T[T[v].ch[0]].is_root=true;
T[v].fa=0;T[v].ch[0]=0;
pushup(v);
}

int n,Q;
int k[maxn];

void debug()
{
puts("------------");
for(int i=1;i<=n+1;i++)
{
printf("%d:",i);
printf("fa:%d l:%d r:%d ir:%d rev:%d s:%d\n",T[i].fa,T[i].ch[0],T[i].ch[1],T[i].is_root,T[i].reverse,T[i].s);
}
puts("------------");
}

int qry(int x)
{
//debug();
mroot(n+1);
//debug();
access(x);
//debug();
Splay(x);
//debug();
return T[T[x].ch[0]].s;
}

void handle(int x,int y)
{
cut(x,min(x+k[x],n+1));
//debug();
k[x]=y;
link(x,min(x+k[x],n+1));
//debug();
}

void solve()
{
T[0].init();
T[0].s=0;
for(int i=1;i<=n;i++)
{
scanf("%d",k+i);
T[i].init();
}
T[n+1].init();
for(int i=1;i<=n;i++)
link(i,min(i+k[i],n+1));
int a,b,c;
scanf("%d",&Q);
while(Q--)
{
scanf("%d %d",&a,&b);
if(a==1) printf("%d\n",qry(b+1));
else
{
scanf("%d",&c);
handle(b+1,c);
}
}
}

int main()
{
while(~scanf("%d",&n)) solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: