记录编号 551020 评测结果 AAAAAAAAAA
题目名称 [HNOI 2010] 弹飞绵羊 最终得分 100
用户昵称 Gravatar瑆の時間~無盡輪迴·林蔭 是否通过 通过
代码语言 C++ 运行时间 2.149 s
提交时间 2020-04-03 00:50:24 内存使用 19.00 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
using namespace std;
const int N=200101;
int st[N];
struct PE
{
	int ch[2],size,fa,lazy;
	PE()
	{
		ch[0]=0;
		ch[1]=0;
		size=0;
		fa=0;
		lazy=0;
	}
};
PE t[N];
int ls(int x)
{
	return t[x].ch[0];
}
int rs(int x)
{
	return t[x].ch[1];
}
bool nroot(int x)
{
	return ls(t[x].fa)==x||rs(t[x].fa)==x;
}
void pushup(int x)
{
	t[x].size=t[ls(x)].size+t[rs(x)].size+1;
}
void round(int x)
{
	int S=t[x].ch[0];
	t[x].ch[0]=t[x].ch[1];
	t[x].ch[1]=S;
	t[x].lazy^=1;
}
void pushdown(int x)
{
	if(t[x].lazy)
	{
		if(ls(x))
		round(ls(x));
		if(rs(x))
		round(rs(x));
		t[x].lazy=0;
	}
}
void rotate(int x)
{
	int y=t[x].fa;
	int z=t[y].fa;
	int k=(t[y].ch[1]==x);
	int w=t[x].ch[k^1];
	if(nroot(y))
	{
		t[z].ch[t[z].ch[1]==y]=x;
	}
	t[y].ch[k]=w;
	if(w)
		t[w].fa=y;
	t[x].ch[k^1]=y;
	t[y].fa=x;
	t[x].fa=z;
	pushup(y);
	pushup(x);
}
void Splay(int x)
{
	int y=x,z=0;
	st[++z]=y;
	while(nroot(y))
	{
		y=t[y].fa;
		st[++z]=y;
	}
	while(z)
	{
		pushdown(st[z--]);
	}
	while(nroot(x))
	{
		y=t[x].fa;
		z=t[y].fa;
		if(nroot(y))
		{
			(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
		}
		rotate(x);
	}
	pushup(x);
}
void Access(int x)
{
	for(int y=0;x;y=x,x=t[x].fa)
	{
		Splay(x);
		t[x].ch[1]=y;
		pushup(x); 
	}
}
void Makeroot(int x)
{
	Access(x);
	Splay(x);
	round(x);
}
void Split(int x,int y)
{
	Makeroot(x);
	Access(y);
	Splay(y);
}
int Findroot(int x)
{
	Access(x);
	Splay(x);
	while(t[x].ch[0])
	{
		pushdown(x);
		x=t[x].ch[0];
	}
	Splay(x);
	return x; 
}
void Link(int x,int y)
{
	Makeroot(x);
	if(Findroot(y)!=x)
	{
		t[x].fa=y;
	}
}
void Cut(int x,int y)
{
	Makeroot(x);
	if(Findroot(y)==x&&t[y].fa==x&&t[y].ch[0]==0)
	{
		t[x].ch[1]=0;
		t[y].fa=0;
		pushup(x);
	}
}
int n,m,a1,a2,a3,a4;
int Val[N];
int main()
{
	freopen("bzoj_2002.in","r",stdin);
	freopen("bzoj_2002.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n+1;i++)
	{
		t[i].size=1;
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&Val[i]);
		Link(i,min(i+Val[i],n+1));
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a1,&a2);
		if(a1==1)
		{
			a2++;
			Split(a2,n+1);
			printf("%d\n",t[n+1].size-1); 
		}
		else
		{
			scanf("%d",&a3);
			a2++;
			Cut(a2,min(a2+Val[a2],n+1));
			Val[a2]=a3;
			Link(a2,min(a2+a3,n+1));
		}
	}
	return 0;
}