bzoj2002 弹飞绵羊 分块

这道题是分块的初尝试 讲给定的区间n进行分块处理 这个每次修改的复杂的只有logn 很方便

代码是学黄学长的 http://hzwer.com/3505.html

当然里面还是有一定我自己的想法在里面的 嫌我代码丑的可以去看黄学长的咯 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
const int M=200007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,block,sum;
int stp[M],w[M],fa[M],belong[M];
int l[1005],r[1005];
int push_ans(int x){
    int ans=0;
    while(1){
        ans+=stp[x];
        if(!fa[x]) break;
        x=fa[x];    
    }
    return ans;    
}
int main()
{
    n=read(); block=sqrt(n);
    for(int i=1;i<=n;i++) w[i]=read();
    if(n%block) sum=n/block+1;
    else sum=n/block;
    for(int i=1;i<=sum;i++) l[i]=r[i-1]+1,r[i]=i*block;
    r[sum]=n;
    for(int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
    for(int i=n;i;i--){
        if(i+w[i]>n) stp[i]=1;
        else if(belong[i]==belong[i+w[i]]) stp[i]=stp[i+w[i]]+1,fa[i]=fa[i+w[i]];
        else stp[i]=1,fa[i]=i+w[i];
    }
    int k,x,y;
    m=read();
    for(int i=1;i<=m;i++){
        k=read();
        if(k==1) x=read()+1,printf("%d
",push_ans(x));
        else{
            x=read()+1; y=read(); w[x]=y;
            for(int j=x;j>=l[belong[x]];j--){
                if(belong[j]==belong[j+w[j]]) stp[j]=stp[j+w[j]]+1,fa[j]=fa[j+w[j]];
                else stp[j]=1,fa[j]=j+w[j];
            }
        }
        //for(int j=1;j<=n;j++) printf("[%d %d] ",fa[j],stp[j]); printf("
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lyzuikeai/p/6962137.html