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;
}
参考博客:
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;
}
相关文章推荐
- 【bzoj2002】【Hnoi2010】【Bounce 弹飞绵羊】【lct】
- bzoj 2002 Bounce 弹飞绵羊(LCT动态树)
- bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊(LCT)
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊(LCT)
- 【BZOJ】2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ2002:Bounce 弹飞绵羊(LCT)
- bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002([Hnoi2010]Bounce 弹飞绵羊-LCT)
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 (LCT)
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 [LCT]
- 【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊(lct)
- [LCT]BZOJ 2002——[Hnoi2010]Bounce 弹飞绵羊
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块/LCT
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【LCT】
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
- 【LCT】BZOJ2002 [Hnoi2010]Bounce 弹飞绵羊
- BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊 LCT
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
- 【LCT】BZOJ2002(Hnoi2010)[Bounce 弹飞绵羊]题解