求助分块
  • 板块学术版
  • 楼主封禁用户
  • 当前回复3
  • 已保存回复4
  • 发布时间2024/12/16 19:07
  • 上次更新2024/12/16 21:59:45
查看原帖
求助分块
608410
封禁用户楼主2024/12/16 19:07

RT, 线段树1用分块写

#include<bits/stdc++.h>

namespace IO {
    inline int read() {
        int ret = 0, f = 1;char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -f;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            ret = (ret << 1) + (ret << 3) + (ch ^ 48);
            ch = getchar();
        }
        return ret * f;
    }
    void write(int x) {
        if (x < 0) putchar('-'), x = -x;
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
}

using namespace std;
using namespace IO;

const int maxn = 1e5 + 5;

int a[maxn], tag[maxn], sum[maxn], f[maxn], L[maxn], R[maxn];
int n, m, len;

int query(int l, int r) {
    int fr = f[l], to = f[r], ans = 0;
    if (fr == to) {
        for (int i = l;i <= r;i++) ans += a[i] + tag[i];
        return ans;
    }
    for (int i = fr + 1;i < to;i++) ans += sum[i];
    for (int i = l;i <= R[fr];i++) ans += a[i] + tag[fr];
    for (int i = L[to];i <= r;i++) ans += a[i] + tag[to];
    return ans;
}

void update(int l, int r, int k) {
    int fr = f[l], to = f[r];
    if (fr == to) {
        for (int i = l;i <= r;i++) a[i] += k, sum[fr] += k;     
        return;
    }
    for (int i = fr + 1;i < to;i++) tag[i] += k, sum[i] += k * (R[i] - L[i] + 1);
    for (int i = l;i <= R[fr];i++) a[i] += k, sum[fr] += k;
    for (int i = L[to];i <= r;i++) a[i] += k, sum[to] += k;
    return;
}

void init() {
    len = sqrt(n);
    for (int i = 1;i <= len;i++) {
        L[i] = (i - 1) * len + 1;
        R[i] = i * len;
        for (int j = L[i];j <= R[i];j++) {
            f[j] = i;
            sum[j] += a[i];
        }
    }
    if (R[len] != n) {
        len++;
        L[len] = R[len - 1] + 1;
        R[len] = n;
        for (int i = L[len];i <= R[len];i++) {
            f[i] = len;
            sum[len] += a[i];
        }
    }
}

int main() {
    n = read(), m = read();
    for (int i = 1;i <= n;i++) a[i] = read();

    init();

    while (m--) {
        int op = read(), x = read(), y = read(), k;
        if (op == 1) {
            k = read();
            update(x, y, k);
        }
        else write(query(x, y)), puts("");
    }

    return 0;
}
2024/12/16 19:07
加载中...