我不是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;
}