BZOJ2002(Hnoi2010)[Bounce 弹飞绵羊]--分块

来源:互联网 发布:无法解析域名错误105 编辑:程序博客网 时间:2024/05/16 06:57

【链接】
bzoj2002

【解题报告】
听说这是裸LCT啊,不会啊,只能用分块大法了,我太弱了QAQ

看题目n挺小的,直接分块大法就好了。

#include<cstdio>#include<cmath>#define Block(x) ((x)-1)/S+1#define min(x,y) ((x)<(y))?(x):(y)using namespace std;const int maxn=200005;int n,m,S,a[maxn],nxt[maxn],p[maxn];inline char nc(){    static char buf[100000],*l=buf,*r=buf;    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);    if (l==r) return EOF; return *l++;}inline int Read(){    int res=0; char ch=nc();    while (ch<'0'||ch>'9') ch=nc();    while (ch>='0'&&ch<='9') res=(res<<3)+(res<<1)+ch-48,ch=nc();    return res;}void Updata(int x){    int s=Block(x),t=Block(x+a[x]);    if (t>s||x+a[x]>n) nxt[x]=min(x+a[x],n+1),p[x]=1;     else nxt[x]=nxt[x+a[x]],p[x]=p[x+a[x]]+1;}int Query(int x) {int sum=0; while (x<=n) sum+=p[x],x=nxt[x]; return sum;}int main(){    freopen("2002.in","r",stdin);    freopen("2002.out","w",stdout);    n=Read(); S=sqrt(n);    for (int i=1; i<=n; i++) a[i]=Read();    for (int i=n; i; i--) Updata(i);    m=Read();    for (int i=1; i<=m; i++)    {        int z=Read(),x=Read()+1;        if (z==1) printf("%d\n",Query(x));         else{a[x]=Read(); for (int i=x,s=(Block(x)-1)*S+1; i>=s; i--) Updata(i);}    }    return 0;}
阅读全文
1 0
原创粉丝点击