BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
逗比的分块处理(反正我是不会写splay的,\(^o^)/~)
分块真是个不错的思想
但是为什么scanf和cout不能套用
我发现这个问题竟然用了一个小时
期间不断RE (%>_<%)
具体看代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 int f[200005]={},to[200005]={},bl[200005]={},k[200005]={},l[200005]={}; 6 int i,j,a,b,n,m,num,x,y,u; 7 int ask(int x) 8 { 9 int s; 10 s=0; 11 while(x<n) 12 { 13 s+=f[x]; 14 x=to[x]; 15 } 16 return s; 17 } 18 void replace(int x,int y) 19 { 20 k[x]=y; 21 int i; 22 for(i=x;i>=l[bl[x]];i--) 23 { 24 if(i+k[i]>=l[bl[i]+1]) 25 { 26 f[i]=1; to[i]=i+k[i]; 27 } 28 else 29 { 30 f[i]=f[i+k[i]]+1; 31 to[i]=to[i+k[i]]; 32 } 33 } 34 } 35 int main() 36 { 37 scanf("%d",&n); 38 num=0; 39 a=sqrt(n); 40 j=a; 41 for(i=0;i<=n-1;i++) 42 { 43 scanf("%d",&b); 44 k[i]=b; 45 if(j==a) 46 { 47 j=1; num++; l[num]=i; 48 } 49 else 50 { 51 j++; 52 } 53 bl[i]=num; 54 } 55 l[num+1]=n; 56 for(i=n-1;i>=0;i--) 57 { 58 if(i+k[i]>=l[bl[i]+1]) 59 { 60 f[i]=1; to[i]=i+k[i]; 61 } 62 else 63 { 64 f[i]=f[i+k[i]]+1; 65 to[i]=to[i+k[i]]; 66 } 67 } 68 scanf("%d",&m); 69 for(i=1;i<=m;i++) 70 { 71 scanf("%d",&u); 72 if(u==1) 73 { 74 scanf("%d",&x); 75 printf("%d\n",ask(x)); 76 } 77 else 78 { 79 scanf("%d%d",&x,&y); 80 replace(x,y); 81 } 82 } 83 return 0; 84 }
和网上标程比较像(o(╯□╰)o)