法一:暴力!

让干什么就干什么,那么久需要可持久化线段树了。

但是空间好紧。怎么破?

不down标记好了!

每个点维护sum和add两个信息,sum是这段真实的和,add是这段整体加了多少,如果这段区间被完全包含,返回sum,否则加上add * 询问落在这段区间的长度再递归回答。

怎么还是MLE?

麻辣鸡指针好像8字节,所以改成数组的就过了。。。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>

using namespace std;

template<typename Q> Q &read(Q &x) {
    static char c, f;
    for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
    for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
    if(f) x = -x; return x;
}
template<typename Q> Q read() {
    static Q x; read(x); return x;
}

typedef long long LL;
const int N = 100000 + 10;
struct Node *pis;
struct Node {
    LL sum, add;
    Node *ch[2];
    
    Node *modify(int l, int r, int L, int R, LL d) {
        Node *o = new Node(*this);
        if(L <= l && r <= R) {
            o->add += d;
            o->sum += (r - l + 1) * d;
            return o;
        }
        int mid = (l + r) >> 1;
        if(L <= mid) o->ch[0] = ch[0]->modify(l, mid, L, R, d);
        if(mid < R) o->ch[1] = ch[1]->modify(mid + 1, r, L, R, d);
        o->sum = o->ch[0]->sum + o->ch[1]->sum + o->add * (r - l + 1);
        return o;
    }
    
    LL query(int l, int r, int L, int R) {
        if(L <= l && r <= R) return sum;
        int mid = (l + r) >> 1;
        LL res = (min(R, r) - max(L, l) + 1) * add;
        if(L <= mid) res += ch[0]->query(l, mid, L, R);
        if(mid < R) res += ch[1]->query(mid + 1, r, L, R);
        return res;
    }
    
    void *operator new(size_t) {
        return pis++;
    }
}pool[1000000 + 10], *root[N];

void build(Node *&o, int l, int r) {
    o = new Node, o->add = 0;
    if(l == r) return read(o->sum), void();
    int mid = (l + r) >> 1;
    build(o->ch[0], l, mid);
    build(o->ch[1], mid + 1, r);
    o->sum = o->ch[0]->sum + o->ch[1]->sum;
}

int main() {
#ifdef DEBUG
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    
    int n, m, cur;
    char opt[10];
    while(scanf("%d%d", &n, &m) == 2) {
        cur = 0, pis = pool;
        build(root[cur], 1, n);
        while(m--) {
            if(m == 1) {
                int debug = 1;
            }
            scanf("%s", opt);
            if(opt[0] == 'C') {
                int l, r; LL d;
                read(l), read(r), read(d);
                root[cur + 1] = root[cur]->modify(1, n, l, r, d);
                cur++;
            }else if(opt[0] == 'Q') {
                int l, r; read(l), read(r);
                printf("%I64d\n", root[cur]->query(1, n, l, r));
            }else if(opt[0] == 'H') {
                int l, r, t; read(l), read(r), read(t);
                printf("%I64d\n", root[t]->query(1, n, l, r));
            }else read(cur);
        }
        puts("");
    }
    
    return 0;
}
指针版

相关文章:

  • 2021-09-27
  • 2021-09-07
猜你喜欢
  • 2021-10-24
  • 2021-12-08
  • 2021-06-22
  • 2022-02-22
  • 2022-12-23
  • 2022-01-27
  • 2021-10-18
相关资源
相似解决方案