BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 [分块]
题意:
修改一个数
从i开始每次到$a_i$,超过n需要几次
分块跑的比LCT都快......
每个块维护块内每个点几步跳出块并跳到哪个位置
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=2e5+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,a[N],Q,op,x; struct Block{ int block,m,pos[N],f[N],g[N]; void ini(){ block=sqrt(n); m=(n-1)/block+1; for(int i=1;i<=n;i++) pos[i]=(i-1)/block+1; //for(int i=1;i<=m;i++) l[i]=(i-1)*block+1,r[i]=i*block; //r[m]=n; for(int i=n;i>=1;i--){ if(pos[i]==pos[a[i]]) f[i]=f[a[i]]+1,g[i]=g[a[i]]; else f[i]=1,g[i]=a[i]; } } int que(int x){ int re=0; for(int i=x;i<=n;i=g[i]) re+=f[i]; return re; } void cha(int x,int v){ a[x]=x+v; int l=(pos[x]-1)*block+1; for(int i=x;i>=l;i--){ if(pos[i]==pos[a[i]]) f[i]=f[a[i]]+1,g[i]=g[a[i]]; else f[i]=1,g[i]=a[i]; } } }B; int main(){ freopen("in","r",stdin); n=read(); for(int i=1;i<=n;i++) a[i]=read()+i; B.ini(); Q=read(); while(Q--){ op=read();x=read()+1; if(op==1) printf("%d\n",B.que(x)); else B.cha(x,read()); } }
Copyright:http://www.cnblogs.com/candy99/