• CF 13E Holes 【块状链表】


    题目描述:

    一条直线上n个点,每个点有个“弹力”,可以把当前位置x上面的ball弹到x+a[x]上面。

    两种操作

    0. 修改a处的弹力值,编程b

    1. 询问a点的ball经过多少次能跳出n个点外(就是出界了)。。。。求出弹跳的次数和最后落脚的点。



    块状链表就是用来暴力模拟的。

    用块状链表可以把时间复杂度从O(n)变成O(sqrt(n))。

    这道题目的复杂度为O(m*sqrt(n))。

    具体实现还是直接看代码容易理解……


    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    using namespace std;
    #define N 100100
    int block[N], c[N], next[N], a[N], end[N];
    int n, m, block_size;
    
    void make(int x) {
        int y = x + a[x];
        if (y <= n && block[x] == block[y]) {
            c[x] = c[y] + 1;
            next[x] = next[y];
            end[x] = end[y];
        } else {
            end[x] = x;
            c[x] = 1;
            next[x] = y;
        }
    }
    void change(int x, int y) {
        a[x] = y;
        for (y=x; y && block[y]==block[x]; y--) make(y);
    }
    
    void ask(int x) {
        int ret = 0, ans;
        for (; x<=n; x=next[x]) {
            ret += c[x];
            ans = end[x];
        }
        cout << ans << " " << ret << endl;
    }
    int main() {
    
        cin >> n >> m;
        block_size = sqrt(n);
    
        for (int i=1; i<=n; i++) {
            cin >> a[i];
            block[i] = i/block_size;
        }
        for (int i=n; i; i--) make(i);
    
        int op, x, y;
        while (m--) {
            cin >> op;
            if (op == 0) {
                cin >> x >> y;
                change(x, y);
            } else {
                cin >> x;
                ask(x);
            }
        }
    
        return 0;
    }


  • 相关阅读:
    学习日记(2.19 BP神经网络完整代码解读)
    学习日记(2.18)
    学习日记2.17
    学习日记(2.15---2.16)
    最后的作业
    C++第五次作业
    第四次作业:结对编程
    C++第四次作业
    第三次作业:原型设计
    conda基本操作
  • 原文地址:https://www.cnblogs.com/aukle/p/3225877.html
Copyright © 2020-2023  润新知