BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊

2002

思路:

处理出块中每个位置跳出当前块的步数以及位置

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define DEBUG
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<long double, long double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 2e5 + 10;
int k[N], bl[N], nx[N], dp[N], blo, n;
void init(int n) {
    blo = sqrt(n);
    for (int i = 1; i <= n; i++) bl[i] = (i-1)/blo + 1;
    for (int i = n; i >= 1; i--) {
        if(i + k[i] > n) {
            dp[i] = 1;
            nx[i] = i+k[i];
        }
        else {
            int pos = i+k[i];
            if(bl[pos] != bl[i]) {
                dp[i] = 1;
                nx[i] = i+k[i];
            }
            else {
                dp[i] = dp[pos] + 1;
                nx[i] = nx[pos];
            }
        }
    }
}
void update(int x, int y) {
    int id = bl[x];
    k[x] = y;
    int l = (id-1)*blo+1, r = min(n, id*blo);
    for (int i = r; i >= l; i--) {
        if(i + k[i] > n) {
            dp[i] = 1;
            nx[i] = i+k[i];
        }
        else {
            int pos = i+k[i];
            if(bl[pos] != bl[i]) {
                dp[i] = 1;
                nx[i] = i+k[i];
            }
            else {
                dp[i] = dp[pos] + 1;
                nx[i] = nx[pos];
            }
        }
    }
}
int query(int x) {
    int ans = 0;
    while(x <= n) {
        ans += dp[x];
        x = nx[x];
    }
    return ans;
}
int main() {
    int op, x, y, m;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &k[i]);
    init(n);
    scanf("%d", &m);
    while(m--) {
        scanf("%d %d", &op, &x);
        x++;
        if(op == 1) {
            printf("%d\n", query(x));
        }
        else {
            scanf("%d", &y);
            update(x, y);
        }
    }
    return 0;
}

 

posted @ 2019-01-23 16:35  Wisdom+.+  阅读(160)  评论(0编辑  收藏  举报