我不是code的生产者,我只是code的搬运工。(咱们码农有力量!)
全当学写lazy标记了= =
PS:说到这个lazy标记,从线段树开始我就不会lazy标记啊,直接导致我一年来再也不写线段树了= =(还好我有两个线段树达人队友,妈妈再也不用担心我的线段树了~)
#include <cstdio> using namespace std; typedef long long ll; const int maxn = 100010; int n, q, a[maxn]; int val[maxn], fa[maxn], ch[maxn][2], size[maxn], root, tot; int add[maxn]; ll sum[maxn]; void init() { root = tot = 0; val[0] = fa[0] = ch[0][0] = ch[0][1] = size[0] = 0; add[0] = sum[0] = 0; } void newnode(int &x, int value, int father) { x = ++tot; val[x] = value; fa[x] = father; ch[x][0] = ch[x][1] = 0; size[x] = 1; add[x] = 0; sum[x] = value; } void push_down(int x) { if (!add[x]) return; val[x] += add[x]; add[ch[x][0]] += add[x]; add[ch[x][1]] += add[x]; sum[ch[x][0]] += (ll)add[x] * size[ch[x][0]]; sum[ch[x][1]] += (ll)add[x] * size[ch[x][1]]; add[x] = 0; } void push_up(int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + 1; sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + val[x] + add[x]; } void rotate(int x, int kind) { int y = fa[x]; push_down(x); push_down(y); ch[y][kind^1] = ch[x][kind]; fa[ch[x][kind]] = y; if (fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; fa[x] = fa[y]; ch[x][kind] = y; fa[y] = x; push_up(y); } void splay(int x, int goal) { push_down(x); while (fa[x] != goal) { int y = fa[x]; if (fa[y] == goal) rotate(x, ch[y][0]==x); else { int kind = ch[fa[y]][0]==y; if (ch[y][kind] == x) {rotate(x, kind^1); rotate(x, kind);} else {rotate(y, kind); rotate(x, kind);} } } push_up(x); if (goal == 0) root = x; } void rotateto(int k, int goal) // 第k位的数 { int x = root; push_down(x); while (size[ch[x][0]] != k-1) { if (size[ch[x][0]] >= k) x = ch[x][0]; else { k -= size[ch[x][0]] + 1; x = ch[x][1]; } push_down(x); } splay(x, goal); } bool insert(int value) { int x = root; if (val[x] == value) return 0; while (ch[x][val[x]<value]) { x = ch[x][val[x]<value]; if (val[x] == value) {splay(x, 0); return 0;} } newnode(ch[x][val[x]<value], value, x); splay(ch[x][val[x]<value], 0); return 1; } void build(int &x, int l, int r, int father) { if (l > r) return; int mid = (l + r) >> 1; newnode(x, a[mid], father); if (l < mid) build(ch[x][0], l, mid-1, x); if (mid < r) build(ch[x][1], mid+1, r, x); push_up(x); } int main() { while (scanf("%d%d", &n, &q) == 2) { for (int i=1;i<=n;i++) scanf("%d", &a[i]); init(); newnode(root, -1, 0); newnode(ch[root][1], -1, root); size[root] = 2; build(ch[ch[root][1]][0], 1, n, ch[root][1]); push_up(ch[root][1]); push_up(root); while (q--) { char cmd[3]; int l, r; scanf("%s%d%d", cmd, &l, &r); rotateto(l, 0); rotateto(r+2, root); if (cmd[0] == 'Q') { printf("%lld\n", sum[ch[ch[root][1]][0]]); } else { int d; scanf("%d", &d); add[ch[ch[root][1]][0]] += d; sum[ch[ch[root][1]][0]] += size[ch[ch[root][1]][0]] * d; } } } return 0; }