存个模板。从其它地方改过来的。。
区间修改,区间查询
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int MAXN = 50010;
struct Node *null;
struct Node{
Node *ch[2], *fa;
int size;
ll lazy, sum, key;
inline void update_add(ll val){
lazy += val;
sum += val * size;
key += val;
}
inline void setc(Node *p, int d){
ch[d] = p;
p->fa = this;
}
inline bool d(){
return fa->ch[1] == this;
}
inline void push_up(){
size = ch[0]->size+ch[1]->size+1;
sum = ch[0]->sum + ch[1]->sum + key;
}
inline void push_down(){
if(lazy){
ch[0]->update_add(lazy);
ch[1]->update_add(lazy);
lazy = 0;
}
}
void clear(int _key){
size = 1;
sum = key = _key;
ch[0] = ch[1] = fa = null;
lazy = 0;
}
};
Node pool[MAXN * 15], *tail;
Node *bc[MAXN];
int bc_top;
void init(){
tail = pool;
bc_top = 0;
null = tail++;
null->size = 0;
null->ch[0] = null->ch[1] = null->fa = null;
}
inline void rotate(Node *x){
Node *f = x->fa, *ff = x->fa->fa;
int c = x->d(), cc = f->d();
f->setc(x->ch[!c], c);
x->setc(f, !c);
if (ff->ch[cc] == f)ff->setc(x, cc);
else x->fa = ff;
f->push_up();
}
void go(Node *x, Node *goal){
if(x != goal) go(x->fa, goal);
x->push_down();
}
inline void splay(Node* &root, Node* x, Node* goal){
go(x, goal);
while (x->fa != goal){
if (x->fa->fa == goal)rotate(x);
else {
bool f = x->fa->d();
x->d() == f ? rotate(x->fa) : rotate(x);
rotate(x);
}
}
x->push_up();
if (goal == null)root = x;
}
Node* newNode(int key){
Node* p;
if (bc_top)p = bc[--bc_top];
else p = tail++;
p->clear(key);
return p;
}
Node* get_kth(Node* x, int k){
x->push_down();
Node*u = x;
while (u->ch[0]->size+1 != k)
{
if (u->ch[0]->size >= k)
u = u->ch[0];
else {
k -= u->ch[0]->size + 1;
u = u->ch[1];
}
u->push_down();
}
return u;
}
Node* build(int l, int r, int *a){
if (l > r)return null;
int mid = (l + r) >> 1;
Node* u = newNode(a[mid]);
u->setc(build(l, mid - 1, a), 0);
u->setc(build(mid + 1, r, a), 1);
u->push_up();
return u;
}
int n, q;
int a[N];
int main(){
while (cin >> n >> q){
for (int i = 1; i <= n; i++)scanf("%d",a+i);
init();
Node* root = build(0, n + 1, a);
Node* lnode,* rnode, *tmp;
char str[2];
while (q--){
int l, r; ll val;
scanf("%s", str); scanf("%d %d", &l, &r);
lnode = get_kth(root, l);
rnode = get_kth(root, r+2);
splay(root, lnode, null);
splay(root, rnode, lnode);
if (str[0] == 'Q')
printf("%lld\n", root->ch[1]->ch[0]->sum);
else {
scanf("%lld", &val);
tmp = root->ch[1]->ch[0];
tmp->update_add(val);
root->ch[1]->push_up();
root->push_up();
}
}
}
return 0;
}