某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
标签:
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
有向边的树写起来似乎还简单点。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 200005 int ch[MAXN][2],fa[MAXN],sz[MAXN],arr[MAXN]; bool rev[MAXN],tp[MAXN]; int n,m; void getint(int &num) { num=0; char c; int flag=1; while((c=getchar())&&!isdigit(c))if(c==‘-‘)flag=-1; while(isdigit(c)){num=num*10+c-48;c=getchar();} } void pushdown(int r) { } void pushup(int r) { sz[r]=sz[ch[r][0]]+sz[ch[r][1]]+1; } void init() { for(int i=1;i<=n;i++) {sz[i]=1; tp[i]=1; } } void rot(int x) { if(x==0||tp[x]==1)return; int y=fa[x],z=fa[y]; pushdown(y),pushdown(x); bool flag=(ch[y][1]==x); ch[y][flag]=ch[x][!flag]; if(ch[y][flag])fa[ch[y][flag]]=y; ch[x][!flag]=y; fa[y]=x; fa[x]=z; if(tp[y]==0)ch[z][ch[z][1]==y]=x; tp[x]=tp[y]; tp[y]=0; sz[x]=sz[y]; pushup(y); } void splay(int x) { pushdown(x); pushup(x); if(tp[x]==1)return; for(;tp[x]==0;rot(x)) { int y=fa[x]; if(tp[y]==0) { int z=fa[y]; rot(((ch[z][1]==y)==(ch[y][1]==x))?y:x); } } pushdown(x); pushup(x); } int access(int x) { int last=0; while(x) { splay(x); if(ch[x][1])tp[ch[x][1]]=1; ch[x][1]=last; tp[last]=0; last=x; pushup(x); x=fa[x]; } } void change(int u,int v) { if(v>n)v=0; splay(u); if(ch[u][0]) {fa[ch[u][0]]=fa[u]; tp[ch[u][0]]=1; } ch[u][0]=0; pushup(u); fa[u]=v; } void link(int u,int v) { if(v) { fa[u]=v; pushup(v); tp[u]=1; } } int main() { getint(n); init(); for(int i=1;i<=n;i++) {getint(arr[i]); link(i,(i+arr[i]>n)?0:(i+arr[i])); } getint(m); int opt,t1,t2; for(int i=1;i<=m;i++) { getint(opt); getint(t1); t1++; if(opt==1) {access(t1); splay(t1); printf("%d\n",sz[t1]); } else { getint(t2); change(t1,t1+t2); } } }
标签:
原文地址:http://www.cnblogs.com/hefenghhhh/p/5028880.html