某天,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的情况,你都要输出一个需要的步数,占一行。
Splay 启发式合并
第一题LCT
参考《QTREE解法的一些研究》
和kuangbin的代码
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (200000+10) #define MAXM (100000+10) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int n,m; class Splay { public: int father[MAXN],siz[MAXN]; int ch[MAXN][2]; bool root[MAXN]; void mem(int n) { MEM(father) MEM(siz) MEM(root) For(i,n+1) siz[i]=1,root[i]=1;root[0]=1; MEM(ch) } void maintain(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void rotate(int x) { int y=father[x],kind=ch[y][1]==x; ch[y][kind]=ch[x][!kind]; if (ch[y][kind]) { father[ch[y][kind]]=y; } father[x]=father[y]; father[y]=x; ch[x][!kind]=y; if (root[y]) { root[x]=1;root[y]=0; } else { ch[father[x]][ ch[father[x]][1]==y ] = x; } maintain(y);maintain(x); } void splay(int x) { while(!root[x]) { int y=father[x]; int z=father[y]; if (root[y]) rotate(x); else if ( (ch[y][1]==x)^(ch[z][1]==y) ) { rotate(x); rotate(x); } else { rotate(y); rotate(x); } } } int access(int x) { int y=0; do { splay(x); if (ch[x][1]) root[ch[x][1]]=1; root[ch[x][1]=y]=0; maintain(x); y = x; x=father [ x]; } while (x) ; return y; } }S; int main() { // freopen("bzoj2002.in","r",stdin); // freopen(".out","w",stdout); cin>>n; S.mem(n); For(i,n) { scanf("%d",&S.father[i]); S.father[i]+=i; if (S.father[i]>n) S.father[i]=n+1; } cin>>m; For(i,m) { int p; scanf("%d",&p); if (p==1) { int x; scanf("%d",&x);x++; S.access(x); S.splay(x); printf("%d\n",S.siz[S.ch[x][0]]); } else { int x,k; scanf("%d%d",&x,&k);x++; k+=x; if (k>n) k=n+1; S.access(x); S.splay(x); S.father[S.ch[x][0]]=S.father[x]; S.father[x]=0; S.root[S.ch[x][0]]=1; S.ch[x][0]=0; S.maintain(x); S.father[x]=k; } } return 0; }
8.28 删除了没有多余的代码
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (200000+10) #define MAXM (100000+10) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int n,m; class Splay { public: int father[MAXN],siz[MAXN]; int ch[MAXN][2]; bool root[MAXN]; void mem(int n) { MEM(father) MEM(siz) MEM(root) For(i,n+1) siz[i]=1,root[i]=1;root[0]=1; MEM(ch) } void maintain(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void rotate(int x) { int y=father[x],kind=ch[y][1]==x; ch[y][kind]=ch[x][!kind]; if (ch[y][kind]) { father[ch[y][kind]]=y; } father[x]=father[y]; father[y]=x; ch[x][!kind]=y; if (root[y]) { root[x]=1;root[y]=0; } else { ch[father[x]][ ch[father[x]][1]==y ] = x; } maintain(y);maintain(x); } void splay(int x) { while(!root[x]) { int y=father[x]; int z=father[y]; if (root[y]) rotate(x); else if ( (ch[y][1]==x)^(ch[z][1]==y) ) { rotate(x); rotate(x); } else { rotate(y); rotate(x); } } } int access(int x) { int y=0; do { splay(x); if (ch[x][1]) root[ch[x][1]]=1; ch[x][1]=y; if (y) root[y]=0; maintain(x); y = x; x=father [x]; } while (x) ; return y; } void cut(int x) { access(x); splay(x); father[ch[x][0]]=0; root[ch[x][0]]=1; ch[x][0]=0; maintain(x); } void join(int x,int w) { father[x]=w; } }S; int main() { // freopen("bzoj2002.in","r",stdin); // freopen(".out","w",stdout); cin>>n; S.mem(n); For(i,n) { scanf("%d",&S.father[i]); S.father[i]+=i; if (S.father[i]>n) S.father[i]=n+1; } cin>>m; For(i,m) { int p; scanf("%d",&p); if (p==1) { int x; scanf("%d",&x);x++; S.access(x); S.splay(x); printf("%d\n",S.siz[S.ch[x][0]]); } else { int x,k; scanf("%d%d",&x,&k);x++; k+=x; if (k>n) k=n+1; S.cut(x); S.join(x,k); } } return 0; }