【bzoj 2002】彈飛綿羊
阿新 • • 發佈:2017-06-24
getchar() esp getchar main output time 需要 top nbsp
Description
某天,Lostmonkey發明了一種超級彈力裝置,為了在他的綿羊朋友面前顯擺,他邀請小綿羊一起玩個遊戲。遊戲一開始,Lostmonkey在地上沿著一條直線擺上n個裝置,每個裝置設定初始彈力系數ki,當綿羊達到第i個裝置時,它會往後彈ki步,達到第i+ki個裝置,若不存在第i+ki個裝置,則綿羊被彈飛。綿羊想知道當它從第i個裝置起步時,被彈幾次後會被彈飛。為了使得遊戲更有趣,Lostmonkey可以修改某個彈力裝置的彈力系數,任何時候彈力系數均為正整數。
Input
第一行包含一個整數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
Output
對於每個i=1的情況,你都要輸出一個需要的步數,占一行。
Sample Input
4
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
唉隔壁都在彈飛大爺了,我還在彈綿羊>_<
分塊大法【Time:1472 ms】
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const intView CodeN=200050; 7 int n,m,num,pl,w,bl,cnt; 8 int k[N],be[N],st[N],to[N]; 9 int read() 10 { 11 int x=0,f=1;char c=getchar(); 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 14 return x*f; 15 } 16 int ask(int t) 17 { 18 intans=st[t]; 19 while(to[t]<=n) 20 { 21 t=to[t]; 22 ans+=st[t]; 23 } 24 return ans; 25 } 26 int main() 27 { 28 n=read();bl=sqrt(n); 29 if(n%bl)cnt=n/bl+1; 30 else cnt=n/bl; 31 for(int i=1;i<=n;i++) 32 { 33 k[i]=read(); 34 be[i]=(i-1)/bl+1; 35 } 36 for(int i=n;i>0;i--) 37 { 38 if(be[i]==be[i+k[i]]){st[i]=st[i+k[i]]+1;to[i]=to[i+k[i]];} 39 else {st[i]=1;to[i]=i+k[i];} 40 } 41 m=read(); 42 while(m--) 43 { 44 num=read();pl=read()+1; 45 if(num==1)printf("%d\n",ask(pl)); 46 else 47 { 48 w=read(); 49 k[pl]=w; 50 int l=(be[pl]-1)*bl+1; 51 for(int i=pl;i>=l;i--) 52 { 53 if(be[i]==be[i+k[i]]){st[i]=st[i+k[i]]+1;to[i]=to[i+k[i]];} 54 else {st[i]=1;to[i]=i+k[i];} 55 } 56 } 57 } 58 return 0; 59 }
LCT【Time:1844 ms】
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=200050; 6 int n,m,c[N][2],next[N],fa[N],size[N],st[N]; 7 bool rev[N]; 8 int read() 9 { 10 int x=0,f=1;char c=getchar(); 11 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 12 while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} 13 return x*f; 14 } 15 bool isroot(int k){return c[fa[k]][0]!=k&&c[fa[k]][1]!=k;} 16 void up(int x){size[x]=size[c[x][0]]+size[c[x][1]]+1;} 17 void down(int x) 18 { 19 int l=c[x][0],r=c[x][1]; 20 if(rev[x]){rev[x]^=1;rev[l]^=1;rev[r]^=1;swap(c[x][0],c[x][1]);} 21 } 22 void rotate(int x) 23 { 24 int y=fa[x],z=fa[y],l,r; 25 if(c[y][0]==x)l=0;else l=1;r=l^1; 26 if(!isroot(y)){if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;} 27 fa[x]=z;fa[y]=x;fa[c[x][r]]=y; 28 c[y][l]=c[x][r];c[x][r]=y; 29 up(y);up(x); 30 } 31 void splay(int x) 32 { 33 int top=0;st[++top]=x; 34 for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i]; 35 for(int i=top;i;i--)down(st[i]); 36 while(!isroot(x)) 37 { 38 int y=fa[x],z=fa[y]; 39 if(!isroot(y)) 40 { 41 if((c[y][0]==x)^(c[z][0]==y))rotate(x); 42 else rotate(y); 43 } 44 rotate(x); 45 } 46 } 47 void acs(int x) 48 { 49 int t=0; 50 while(x){splay(x);c[x][1]=t;t=x;x=fa[x];} 51 } 52 void mkroot(int x) 53 { 54 acs(x);splay(x);rev[x]^=1; 55 } 56 void link(int x,int y) 57 { 58 mkroot(x);fa[x]=y;splay(x); 59 } 60 void cut(int x,int y) 61 { 62 mkroot(x);acs(y);splay(y);c[y][0]=fa[x]=0; 63 } 64 int main() 65 { 66 n=read(); 67 for(int i=1;i<=n;i++) 68 { 69 int x=read(); 70 fa[i]=x+i;size[i]=1; 71 if(fa[i]>n+1)fa[i]=n+1; 72 next[i]=fa[i]; 73 } 74 size[n+1]=1; 75 m=read(); 76 while(m--) 77 { 78 int f=read(); 79 if(f==1) 80 { 81 mkroot(n+1); 82 int x=read()+1; 83 acs(x);splay(x);printf("%d\n",size[c[x][0]]); 84 } 85 else 86 { 87 int x=read()+1,y=read(); 88 int t=min(n+1,x+y); 89 cut(x,next[x]);link(x,t);next[x]=t; 90 } 91 } 92 return 0; 93 }View Code
【bzoj 2002】彈飛綿羊