# 【HNOI2010】【BZOJ2002】Bounce 弹飞绵羊

Description

Input

Output

Sample Input

4

1 2 1 1

3

1 1

2 1 1

1 1

Sample Output

2

3

HINT

Source

Splay 启发式合并

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200100
using namespace std;
int n,m;
int k[MAXN];
int sta[MAXN],top;
int opt,u,v;
struct splay
{
int fa,ch[2],size;
bool rev;
}tree[MAXN];
inline void in(int &x)
{
char ch=getchar();int flag=1;x=0;
while (!(ch>='0'&&ch<='9')) flag=ch=='-'?-1:1,ch=getchar();
while (ch>='0'&&ch<='9')    x=x*10+ch-'0',ch=getchar();
}
inline bool is_root(int x)
{
return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;
}
inline void push_down(int x)
{
if (tree[x].rev)
{
tree[x].rev^=1;tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1;
swap(tree[x].ch[0],tree[x].ch[1]);
}
}
inline void push_up(int x)
{
tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1;
}
inline void rot(int x)
{
int y=tree[x].fa,z=tree[y].fa,l,r;
l=(tree[y].ch[1]==x);r=l^1;
if (!is_root(y))    tree[z].ch[tree[z].ch[1]==y]=x;
tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z;
tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y;
push_up(x);push_up(y);
}
inline void Splay(int x)
{
sta[++top]=x;
for (int i=x;!is_root(i);i=tree[i].fa)  sta[++top]=tree[i].fa;
while (top) push_down(sta[top--]);
while (!is_root(x))
{
int y=tree[x].fa,z=tree[y].fa;
if (!is_root(y))
{
if (tree[y].ch[0]==x^tree[z].ch[0]==y)  rot(x);
else    rot(y);
}
rot(x);
}
}
inline void access(int x)
{
for (int i=0;x;i=x,x=tree[x].fa)    Splay(x),tree[x].ch[1]=i,push_up(x);
}
inline void make_root(int x)
{
access(x);Splay(x);tree[x].rev^=1;
}
{
Splay(x);tree[x].fa=y;
}
inline void cut(int x,int y)
{
make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;
}
inline int find(int x)
{
access(x);Splay(x);
int ret=x;
while (tree[ret].ch[0]) ret=tree[ret].ch[0];
return ret;
}
int main()
{
in(n);tree[n+1].size=1;
for (int i=1;i<=n;i++)
{
scanf("%d",&k[i]);
tree[i].size=1;tree[i].fa=min(i+k[i],n+1);
}
in(m);
while (m--)
{
in(opt);
if (opt==1)
{
in(u);u++;make_root(n+1);
access(u);Splay(u);
printf("%d\n",tree[tree[u].ch[0]].size);
}
if (opt==2)
{
in(u);in(v);u++;
}