zoukankan      html  css  js  c++  java
  • P3203 [HNOI2010]弹飞绵羊

    题目
    暴力时间复杂度是(O(n^2))
    涉及到区间的题,可以用分块去操作
    那么记录每个点出所在的分块所需要次数和出分块后的位置即可
    然后暴力

    对于非典型分块,需要处理好每个分块的左右区间,以及0和n + 1所在分块情况

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int N = 2e5 + 5;
    int n, m, unt;
    int bl[N], a[N], to[N], f[N], l[N];
    void Change(int pos, int k){
        a[pos] = k;
        for(int i = l[bl[pos] + 1] - 1; i >= l[bl[pos]]; i--){
            if(i + a[i] >= l[bl[i] + 1]){
                f[i] = 1;
                to[i] = i + a[i];
            }else{
                f[i] = f[i + a[i]] + 1;
                to[i] = to[i + a[i]];
            }
        }
    }
    int Query(int pos){
        int ans = 0;
        while(pos <= n){
            ans += f[pos];
            pos = to[pos];
        }
        return ans;
    }
    int main(){
        scanf("%d", &n);
        unt = sqrt(n);
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            bl[i] = (i - 1) / unt + 1;
            if (bl[i] != bl[i - 1]) l[bl[i]] = i;
        }
        l[bl[n] + 1] = n + 1;
        for(int i = n; i >= 1; i--){
            if(i + a[i] >= l[bl[i] + 1]){
                f[i] = 1;
                to[i] = i + a[i];
            }else{
                f[i] = f[i + a[i]] + 1;
                to[i] = to[i + a[i]];
            }
        }
        scanf("%d", &m);
        while(m--){
            int op, x, k;
            scanf("%d", &op);
            if(op == 1){
                scanf("%d", &x);
                printf("%d
    ", Query(x + 1));
            }else{
                scanf("%d%d", &x, &k);
                Change(x + 1, k);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HBase 安装设置
    Python中通过函数对象创建全局变量
    Scala 中 构造函数,重载函数的执行顺序
    Hive 安装配置
    976. 三角形的最大周长
    922. 按奇偶排序数组 II
    350. 两个数组的交集 II
    349. 两个数组的交集
    242. 有效的字母异位词
    925. 长按键入
  • 原文地址:https://www.cnblogs.com/Emcikem/p/12921390.html
Copyright © 2011-2022 走看看