# bzoj2002 [Hnoi2010]Bounce flying sheep

Posted by Pezmc on Sun, 03 May 2020 10:04:44 +0200

# Description

One day, Lostmonkey invented a super elastic device. In order to show off in front of his sheep friends, he invited the little sheep to play a game together. At the beginning of the game, Lostmonkey placed n devices along a straight line on the ground. Each device set the initial elastic coefficient ki. When the sheep reached the I device, it would play back ki steps to reach the i+ki device. If there was no i+ki device, the sheep would be bounced. The sheep wanted to know that when it started from the i-th device, it would be bounced off after being bounced several times. In order to make the game more interesting, Lostmonkey can modify the elasticity coefficient of a certain elastic device, which is a positive integer at any time.

20% data n, m < = 10000
100% data n < = 200000, m < = 100000

# Solution

Another LCT naked question. After reading the question, my brain made up a moving tree-_-||
The distance from the point to the root is required here. Obviously, violent jumping is not allowed. Splay maintains the size of an interval. First access(x) and then rotate x to the root of splay to know the depth through the size of the left son of the root
It's said that it can be done in blocks

# Code

```#include <stdio.h>
#include <algorithm>
const int N=400005;
struct treeNode{int son,fa,lazy,size; bool is_root;}t[N];
int a[N],n;
void push_up(int x) {
t[x].size=t[t[x].son].size+t[t[x].son].size+1;
}
void push_down(int x) {
if (!t[x].lazy||!x) return ;
std:: swap(t[x].son,t[x].son);
t[t[x].son].lazy^=1;
t[t[x].son].lazy^=1;
t[x].lazy=0;
}
void rotate(int x) {
if (t[x].is_root) return ;
int y=t[x].fa; int z=t[y].fa;
int k=t[y].son==x;
t[y].son[k]=t[x].son[!k];
if (t[x].son[!k]) t[t[x].son[!k]].fa=y;
t[x].son[!k]=y;
t[y].fa=x;
t[x].fa=z;
if (t[y].is_root) {
t[x].is_root=1;
t[y].is_root=0;
} else t[z].son[t[z].son==y]=x;
push_up(y);
push_up(x);
}
void remove(int x) {
if (!t[x].is_root) remove(t[x].fa);
push_down(x);
}
void splay(int x) {
remove(x);
while (!t[x].is_root) {
int y=t[x].fa; int z=t[y].fa;
if (!t[y].is_root) {
if ((t[y].son==x)^(t[z].son==y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x) {
int y=0;
do {
splay(x);
t[t[x].son].is_root=1;
t[t[x].son=y].is_root=0;
push_up(x);
y=x; x=t[x].fa;
} while (x);
}
void mroot(int x) {
access(x); splay(x);
t[x].lazy^=1;
}
if (y>n) y=n+1;
mroot(x); t[x].fa=y;
splay(x);
}
void cut(int x,int y) {
if (y>n) y=n+1;
mroot(x); access(y); splay(y);
t[t[y].son].is_root=1;
t[t[y].son].fa=0;
t[y].son=0;
push_up(y);
}
int query(int x) {
mroot(n+1);
access(x); splay(x);
return t[t[x].son].size;
}
int main(void) {
scanf("%d",&n);
for (int i=1;i<=n+1;i++) t[i].is_root=t[i].size=1;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) {
}
int m; scanf("%d",&m);
while (m--) {
int opt,x; scanf("%d%d",&opt,&x); x++;
if (opt==1) {
printf("%d\n", query(x));
} else {
int y; scanf("%d",&y);
cut(x,x+a[x]);
a[x]=y;