题意:
给你n个数字,m组修改或者询问操作,修改为区间修改,询问也是区间和的询问。
分析:
很简单的一道线段树Lazy练习题,用来练习Splay的区间维护也是一个不错的选择,使用标记来加快速度,最后注意答案要开long long即可Ac
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn = 100000 + 10;
const int INF = 0x3f3f3f3f;
struct SplayTree {
int n, root;
LL Sum[maxn];
int c[maxn][2], fa[maxn], id[maxn];
int Val[maxn], Add[maxn], Rank[maxn], size[maxn];
void init() {
n = root = 0;
memset(c, 0, sizeof(c));
memset(fa, 0, sizeof(fa));
memset(id, 0, sizeof(id));
memset(Rank, 0, sizeof(Rank));
}
int Newnode(int val, int k) {
++n;
Val[n] = Sum[n] = val; Add[n] = 0;
Rank[n] = k; size[n] = 1; id[k] = n;
return n;
}
void Push_up(int u) {
size[u] = size[c[u][0]] + size[c[u][1]] + 1;
Sum[u] = Sum[c[u][0]] + Sum[c[u][1]] + Val[u] + Add[u];
}
void Push(int u) {
if(fa[u]) Push(fa[u]);
Push_down(u);
}
void Push_down(int u) {
if(Add[u]) {
Val[u] += Add[u];
Add[c[u][0]] += Add[u];
Add[c[u][1]] += Add[u];
Sum[c[u][0]] += (LL)Add[u] * size[c[u][0]];
Sum[c[u][1]] += (LL)Add[u] * size[c[u][1]];
}Add[u] = 0;
}
void rotate(int u) {
int v = fa[u], w = fa[v], t = c[v][1] == u;
fa[c[u][t^1]] = v, c[v][t] = c[u][t^1];
c[u][t^1] = v; fa[u] = w; fa[v] = u;
if(root == v) root = u;
else c[w][c[w][1] == v] = u;
Push_up(v);
}
void Splay(int u, int pos) {
Push(u);
while(fa[u] != pos) {
int v = fa[u], w = fa[v];
if(fa[v] == pos)
rotate(u);
else if((c[v][0] == u) == (c[w][0] == v))
rotate(v), rotate(u);
else
rotate(u), rotate(u);
}Push_up(u);
}
void join(int u, int k, int val) {
int d = k >= Rank[u];
c[u][d] = Newnode(val, k); fa[n] = u;
int t = n;
while(t) {
Push_up(t);
t = fa[t];
}
Splay(n, 0);
}
void insert(int k, int val, int u) {
int d = k >= Rank[u];
if(c[u][d])
insert(k, val, c[u][d]);
else join(u, k, val);
}
void update(int u, int v, int w) {
Splay(id[u-1], 0);
Splay(id[v+1], root);
Add[c[id[v+1]][0]] += w;
Sum[c[id[v+1]][0]] += (LL)size[c[id[v+1]][0]] * w;
}
LL query(int x, int y) {
Splay(id[x-1], 0);
Splay(id[y+1], root);
return Sum[c[id[y+1]][0]];
}
}SPT;
char s[20];
int n, m, u, v, w;
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt", "r", stdin);
freopen("ans.txt", "w", stdout);
#endif
scanf("%d%d", &n, &m);
SPT.root = SPT.Newnode(0, 0);
for(int i=1; i<=n; i++) {
scanf("%d", &u);
SPT.insert(i, u, SPT.root);
}
SPT.insert(n+1, 0, SPT.root);
while(m--) {
scanf("%s%d%d", s, &u, &v);
if(s[0] == 'C') {
scanf("%d", &w);
SPT.update(u, v, w);
}else
printf("%lld\n", SPT.query(u, v));
}
return 0;
}