HNOI2010彈飛綿羊

話說我是冒着巨大的風險A這道題的(xc說不讓上其他oj)。
這題其實很簡單,每個點如果他能往後跳,那就只能跳到唯一的一個,這顯然是跟森林,用lct就好,維護下size。
代碼突然變短

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define lc c[x][0]
#define rc c[x][1]
using namespace std;
const int N=200000+5;
int c[N][2],s[N],f[N],r[N],k[N];
int n,m,flag,x,y;
void R(int &x){
	int t=0; char ch;
	for (ch=getchar();!('0'<=ch&&ch<='9');ch=getchar());
	for (;('0'<=ch&&ch<='9');ch=getchar()) t=t*10+ch-'0';
	x=t;
}
bool wh(int x){
	return x==c[f[x]][1];
}
bool nroot(int x){
	return x==c[f[x]][0]||x==c[f[x]][1];
}
void update(int x){
	s[x]=1+s[lc]+s[rc];
}
void rotate(int x){
	int y=f[x],z=f[y],k=wh(x),w=c[x][1^k];
	if (nroot(y)) c[z][wh(y)]=x; f[x]=z;
	c[y][k]=w; if (w) f[w]=y;
	c[x][1^k]=y; f[y]=x;
	update(y); update(x);
}
void splay(int x){
	for (;nroot(x);rotate(x))
		if (nroot(f[x]))
			rotate(wh(x)==wh(f[x])?f[x]:x);
}
void access(int x){
	for (int y=0;x;x=f[y=x])
		splay(x),rc=y,update(x);
}
int main(){
	//freopen("bzoj2002.in","r",stdin);
	//freopen("bzoj2002.out","w",stdout);
	R(n);
	fo(i,1,n){
		R(k[i]);
		if (k[i]+i<=n) f[i]=k[i]+i;
		s[i]=1;
	}
	R(m);
	while (m--){
		R(flag); R(x); x++;
		if (flag==1){
			access(x); splay(x); printf("%d\n",s[x]);
		}
		else{
			R(y);
			access(x); splay(x); 
			lc=f[lc]=0;
			if (y+x<=n) f[x]=x+y;
			update(x);
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章