1. 程式人生 > >【bzoj 2002】彈飛綿羊

【bzoj 2002】彈飛綿羊

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 int
N=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 int
ans=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 }
View Code

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】彈飛綿羊