zoukankan      html  css  js  c++  java
  • bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊 分块

    题目链接

    Description

    某天,(Lostmonkey)发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,(Lostmonkey)在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数(k_i),当绵羊达到第i个装置时,它会往后弹(k_i)步,达到第(i+k_i)个装置,若不存在第(i+k_i)个装置,则绵羊被弹飞。绵羊想知道当它从第(i)个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,(Lostmonkey)可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

    思路

    分块,维护:

    1. 每个点跳几次跳到下一个块
    2. 跳到下一个块的什么位置

    初始化:(O(n))
    修改:(O(sqrt n))
    查询:(O(sqrt n))

    Code

    #include <bits/stdc++.h>
    #define F(i, a, b) for (int i = (a); i < (b); ++i)
    #define F2(i, a, b) for (int i = (a); i <= (b); ++i)
    #define dF(i, a, b) for (int i = (a); i > (b); --i)
    #define dF2(i, a, b) for (int i = (a); i >= (b); --i)
    #define maxn 200010
    using namespace std;
    typedef long long LL;
    int a[maxn], n, blo, bl[maxn], num;
    struct node { int cnt, p; }v[maxn];
    void init() {
        F(i, 0, num) {
            int ed = min((i+1)*blo-1, n-1),
                st = i*blo;
            dF2(j, ed, st) {
                int ne = j+a[j];
                if (ne>ed) v[j] = {1, ne};
                else v[j] = v[ne], ++v[j].cnt;
            }
        }
    }
    void modify(int x, int c) {
        a[x] = c;
        int st = bl[x]*blo, ed = min((bl[x]+1)*blo-1, n-1);
        dF2(i, x, st) {
            int ne = i+a[i];
            if (ne > ed) v[i] = {1, ne};
            else v[i] = v[ne], ++v[i].cnt;
        }
    }
    int query(int x) {
        int ret=0;
        while (x < n) {
            ret += v[x].cnt;
            x = v[x].p;
        }
        return ret;
    }
    int main() {
        scanf("%d", &n); blo = sqrt(n);
        F(i, 0, n) {
            scanf("%d", &a[i]);
            bl[i] = i/blo;
        }
        num = bl[n-1]+1;
        init();
        int m;
        scanf("%d", &m);
        F(i, 0, m) {
            int op, x, y;
            scanf("%d", &op);
            if (op==1) {
                scanf("%d",&x);
                printf("%d
    ", query(x));
            }
            else {
                scanf("%d%d", &x,&y);
                modify(x,y);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    linux 计划任务
    linux 进程管理
    PHP中global与$GLOBALS['']的区别
    php预定义变量
    linux 强制终止进程命令
    mysql取某表中数据的随机的方法
    mysql 连接 选库 查询
    Python 的异步 IO:Asyncio 简介
    并发和并行的区别
    asyncio模块中的Future和Task
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/8479764.html
Copyright © 2011-2022 走看看