1. 程式人生 > 其它 >LOJ6277. 數列分塊入門 1 題解

LOJ6277. 數列分塊入門 1 題解

題目連結:https://loj.ac/p/6277

涉及操作:

  1. 區間更新;
  2. 單點查詢。

解題思路:

數列分塊。

  • a[i] 表示:第i個數自己儲存的值
  • block 表示每個分塊的最大尺寸
  • belong[i] 表示:第i個數所屬的分塊
  • tag[i] 表示:第i個分塊的累加值

示例程式:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 50050;
/**
    a[i] 表示:第i個數自己儲存的值
    block: 表示每個分塊的最大尺寸
    belong[i] 表示:第i個數所屬的分塊
    tag[i] 表示:第i個分塊的累加值
*/
int n, block, a[maxn], belong[maxn], tag[maxn];

void add(int l, int r, int val) {   // 將 [l,r] 都加val
    for (int i = l; i <= min(belong[l]*block, r); i ++)
        a[i] += val;
    if (belong[l] != belong[r])
        for (int i = (belong[r]-1)*block+1; i <= r; i ++)
            a[i] += val;
    for (int i = belong[l]+1; i < belong[r]; i ++)
        tag[i] += val;
}

int main() {
    ios::sync_with_stdio(0);
    cin >> n;
    block = sqrt(n);
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        belong[i] = (i - 1) / block + 1;
    }
    for (int i = 0; i < n; i ++) {
        int op, l, r, c;
        cin >> op >> l >> r >> c;
        if (op == 0) {  // 將[l,r]都加c
            add(l, r, c);
        }
        else {  // 詢問 a[r] 的值
            cout << a[r] + tag[belong[r]] << endl;
        }
    }
    return 0;
}

學習資料:http://hzwer.com/8053.html