zoukankan      html  css  js  c++  java
  • LOJ6278. 数列分块入门 2 题解

    题目链接:https://loj.ac/p/6278

    涉及操作:

    1. 区间加法;
    2. 区间询问小于某个值 (x) 的数的个数。

    解题思路:

    数列分块。

    每个分块保存一个副本并排序(程序中用 vector 容器 vec[i] 来保存第 i 个分块中的信息)。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 50050;
    int n, blo, a[maxn], bl[maxn], tag[505];
    vector<int> vec[505];
    
    // 重置第p个分块
    void reset(int p) {
        vec[p].clear();
        for (int i = (p-1)*blo+1; i <= min(p*blo, n); i ++)
            vec[p].push_back(a[i]);
        sort(vec[p].begin(), vec[p].end());
    }
    
    // 区间 [l,r] + val
    void add(int l, int r, int val) {
        for (int i = l; i <= min(bl[l]*blo, r); i ++)
            a[i] += val;
        reset(bl[l]);
        if (bl[l] != bl[r]) {
            for (int i = (bl[r]-1)*blo+1; i <= r; i ++)
                a[i] += val;
            reset(bl[r]);
        }
        for (int i = bl[l]+1; i < bl[r]; i ++)
            tag[i] += val;
    }
    
    // 返回区间 [l,r] 内小于 val 的数的个数
    int query(int l, int r, int val) {
        int ans = 0;
        for (int i = l; i <= min(bl[l]*blo, r); i ++)
            if (a[i] + tag[bl[i]] < val)
                ans ++;
        if (bl[l] != bl[r]) {
            for (int i = (bl[r]-1)*blo+1; i <= r; i ++)
                if (a[i] + tag[bl[i]] < val)
                    ans ++;
        }
        for (int i = bl[l]+1; i < bl[r]; i ++) {
            ans += lower_bound(vec[i].begin(), vec[i].end(), val-tag[i]) - vec[i].begin();
        }
        return ans;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n;
        blo = sqrt(n);
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            bl[i] = (i - 1) / blo + 1;
        }
        for (int i = 1; i <= bl[n]; i ++)
            reset(i);
        for (int i = 0; i < n; i ++) {
            int op, l, r, c;
            cin >> op >> l >> r >> c;
            if (op == 0) {
                add(l, r, c);
            }
            else {
                cout << query(l, r, c*c) << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    How to Change Error Message Colors in Windows 10 PowerShell Console
    How to expand Azure VM OS Disk
    Ubuntu terminal colors
    Docker proxy
    如何对mRemoteNG在进行Linux终端访问时自定义配色
    100阶乘末尾有多少个零
    几道c/c++练习题
    M-BM-
    从FGUI中取一张图片并返回一个Sprite
    为什么手游选择lua热更新方案。
  • 原文地址:https://www.cnblogs.com/quanjun/p/15524490.html
Copyright © 2011-2022 走看看