这个线段树的模板题为什么分块都能过?
查看原帖
这个线段树的模板题为什么分块都能过?
528472
myster1ous楼主2022/5/26 23:02

rt,我不会线段树,所以只好打了个分块,结果就过了。

建议加大数据范围。

record

#include <bits/stdc++.h>
#define int int64_t
#define maxn 131072
using namespace std;
int a[maxn], n, ms, q;
int s[maxn], m[maxn], b[maxn], e[maxn], add[maxn], siz[maxn];
namespace block{
    void build();
    void update(int, int, int);
    int query(int, int);
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n >> ms;
    q = sqrt(n);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    block::build();
    for (int i = 1; i <= ms; i++) {
        int mode, x, y, k;
        cin >> mode;
        if (mode == 1) {
            cin >> x >> y >> k;
            block::update(x, y, k);
        } else {
            cin >> x >> y;
            cout << block::query(x, y) << "\n";
        }
    }
    return 0;
}
void block::build() {
    for (int i = 1; i <= q; i++) {
        b[i] = n / q * (i - 1) + 1;
        e[i] = n / q * i;
    }
    e[q] = n;
    for (int i = 1; i <= q; i++)
        siz[i] = e[i] - b[i] + 1;
    for (int i = 1; i <= q; i++)
        for (int j = b[i]; j <= e[i]; j++)
            m[j] = i;
    for (int i = 1; i <= q; i++)
        for (int j = b[i]; j <= e[i]; j++)
            s[i] += a[j];
}
void block::update(int x, int y, int k) {
    if (m[x] == m[y]) {
        for (int i = x; i <= y; i++) {
            s[m[i]] += k;
            a[i] += k;
        }
    } else {
        for (int i = x; i <= e[m[x]]; i++) {
            s[m[i]] += k;
            a[i] += k;
        }
        for (int i = b[m[y]]; i <= y; i++) {
            s[m[i]] += k;
            a[i] += k;
        }
        for (int i = m[x] + 1; i < m[y]; i++) 
            add[i] += k;
    }
}
int block::query(int x, int y) {
    int q = 0;
    if (m[x] == m[y]) {
        for (int i = x; i <= y; i++)
            q += a[i] + add[m[i]];
    } else {
        for (int i = x; i <= e[m[x]]; i++)
            q += a[i] + add[m[i]];
        for (int i = b[m[y]]; i <= y; i++)
            q += a[i] + add[m[i]];
        for (int i = m[x] + 1; i < m[y]; i++)
            q += s[i] + add[i] * siz[i];
    }
    return q;
}
2022/5/26 23:02
加载中...