您的位置:首页 > 其它

BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 动态树

2017-09-04 20:15 260 查看

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002

题意:加边,删边,查询到根的距离。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int ch[maxn][2], pre[maxn], rev[maxn], Next[maxn];
int size[maxn];
bool rt[maxn];
void Update_Rev(int r){
if(!r) return;
swap(ch[r][0], ch[r][1]);
rev[r] ^= 1;
}
void push_down(int r){
if(rev[r]){
Update_Rev(ch[r][0]);
Update_Rev(ch[r][1]);
rev[r] = 0;
}
}
void push_up(int r){
size[r] = size[ch[r][0]]+size[ch[r][1]]+1;
}
void Rotate(int x){
int y = pre[x], kind = ch[y][1] == x;
ch[y][kind] = ch[x][!kind];
pre[ch[y][kind]] = y;
pre[x] = pre[y];
pre[y] = x;
ch[x][!kind] = y;
if(rt[y])
rt[y] = false, rt[x] = true;
else
ch[pre[x]][ch[pre[x]][1]==y]=x;
push_up(y);
}
void P(int r){
if(!rt[r]) P(pre[r]);
push_down(r);
}
void Splay(int r){
P(r);
while(!rt[r]){
int f = pre[r], ff = pre[f];
if(rt[f])
Rotate(r);
else if((ch[ff][1]==f)==(ch[f][1]==r))
Rotate(f), Rotate(r);
else Rotate(r), Rotate(r);
}
push_up(r);
}
int Access(int x){
int y = 0;
for(;x;x=pre[y=x]){
Splay(x);
rt[ch[x][1]] = true, rt[ch[x][1]=y] = false;
push_up(x);
}
return y;
}
void mroot(int r){
Access(r);
Splay(r);
Update_Rev(r);
}
void link(int u, int v){
mroot(u);
pre[u] = v;
}
void cut(int u, int v){
mroot(u);
Splay(v);
pre[ch[v][0]] = pre[v];
pre[v] = 0;
rt[ch[v][0]] = true;
ch[v][0] = 0;
push_up(v);
}
int n, m;
int main()
{
scanf("%d", &n);
for(int i=0; i<=n+1; i++){
pre[i]=0;
ch[i][0]=ch[i][1]=0;
rev[i]=0;
rt[i] = true;
size[i] = 0;
}
for(int i=1,t; i<=n; i++){
scanf("%d", &t);
t = min(i+t, n+1);
pre[i] = Next[i] = t;
size[i] = 1;
}
size[n+1] = 1;
scanf("%d", &m);
int op, x, y;
for(int i=1; i<=m; i++){
scanf("%d%d", &op,&x);
x++;
if(op==1){
mroot(n+1);
Access(x);
Splay(x);
printf("%d\n", size[ch[x][0]]);
}
else{
scanf("%d", &y);
y = min(x+y,n+1);
cut(x,Next[x]);
link(x,y);
Next[x]=y;
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: