HYSBZ 2002 Bounce 弹飞绵羊(分块)

今天原来打算做ZOJ月赛的,等到中午的时候感觉太困了,就睡了一觉,然后就没有然后了。。。

这题正版写法应该是LCT,但是分块也能过,而且写起来特别简单,LCT写的话应该是一个Cut,Link操作,维护的就是答案的值(没写)。

下面附上代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define LL long long
#define FOR(i,x,y)  for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define MAXN 220000

using namespace std;

int n,m,ct[MAXN],nt[MAXN],val[MAXN];
int blocks;

void Modify(int u,int v){
    nt[u] = v;
    ct[u] = 1;
    if(v >= n)  return;
    if(u/blocks == v/blocks){
        ct[u] += ct[v];
        nt[u] = nt[v];
    }
}

int Query(int x){
    int ans = 0;
    while(x < n){
        ans += ct[x];
        x = nt[x];
    }
    return ans;
}

int main()
{
    //freopen("test.in","r",stdin);
    while(~scanf("%d",&n)){
        FOR(i,0,n)  scanf("%d",&val[i]);
        blocks = (int)sqrt(n+0.5) + 1;
        IFOR(i,n-1,-1){
            Modify(i,i+val[i]);
        }
        scanf("%d",&m);
        FOR(i,0,m){
            int op;
            scanf("%d",&op);
            if(op == 1){
                int x;
                scanf("%d",&x);
                printf("%d\n",Query(x));
            }
            else{
                int x,w;
                scanf("%d%d",&x,&w);
                val[x] = w;
                int u = x/blocks*blocks;
                IFOR(i,x,u-1){
                    Modify(i,i + val[i]);
                }
            }
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-09-12 16:43  hqwhqwhq  阅读(123)  评论(0编辑  收藏  举报