首页 > 代码库 > HYSBZ_2002_分块

HYSBZ_2002_分块

http://www.lydsy.com/JudgeOnline/problem.php?id=2002

 

分块基础题,初次接触,很巧妙。

OJ好像挂了,没法提交。

 

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;int a[200005],cnt[200005],next[200005],l[1000],r[1000],belong[200005],n,m;void build(){    int block = sqrt(n);    int num = n/block;    if(n%block) num++;    for(int i = 1;i <= num;i++)    {        l[i] = (i-1)*block+1;        r[i] = i*block;    }    r[num] = n;    for(int i = 1;i <= n;i++)   belong[i] = (i-1)/block+1;    for(int i = n;i >= 1;i--)    {        int temp = i+a[i];        if(temp > n)        {            cnt[i] = 1;            next[i] = -1;        }        else if(belong[i] == belong[temp])        {            cnt[i] = cnt[temp]+1;            next[i] = next[temp];        }        else        {            cnt[i] = 1;            next[i] = temp;        }    }}int getsum(int x){    int ans = cnt[x];    while(next[x] > 0)    {        x = next[x];        ans += cnt[x];    }    return ans;}void update(int x,int y){    a[x] = y;    for(int i = x;i >= l[belong[x]];i--)    {        int temp = i+a[i];        if(temp > n)        {            cnt[i] = 1;            next[i] = -1;        }        else if(belong[i] == belong[temp])        {            cnt[i] = cnt[temp]+1;            next[i] = next[temp];        }        else        {            cnt[i] = 1;            next[i] = temp;        }    }}int main(){    scanf("%d",&n);    for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);    build();    scanf("%d",&m);    while(m--)    {        int i,j,k;        scanf("%d%d",&i,&j);        if(i == 1)  printf("%d\n",getsum(j+1));        else        {            scanf("%d",&k);            update(j+1,k);        }    }    return 0;}

 

HYSBZ_2002_分块