线段树模板
这个人很懒,什么也不想写了。(都写在注释好了)
建议先学线段树之后再来看模板,这是自己用的模板,我自己感觉用的很舒畅,模板还是用自己喜欢的最好。
/*************************************************************************
> Problem: 线段树模板
> Author: ALizen_
> Mail: hhu_zyh@qq.com
> Blog: https://blog.csdn.net/Jame_19?spm=1001.2101.3001.5343
*************************************************************************/
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register int
#define sf(x) scanf("%d",&x)
#define pf(x) printf("%d\n",x)
#define slf(x) scanf("%lld",&x)
#define plf(x) printf("%lld\n",x)
#define MEM(a,b) memset((a),(b),sizeof(a))
#define ref(i,a,b) for(re i = a ; i >= b ; -- i)
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int w[N];
struct node {
int l, r;
LL val;
LL lazy;
}t[N << 2];//要开N的四倍,N左移两位和N*4等价
void pushdown(node& op, LL lazy) {
op.val += lazy * (op.r - op.l + 1);
op.lazy += lazy;
}//用来重载
void pushdown(int x) {
if (!t[x].lazy) return;
pushdown(t[x << 1], t[x].lazy);
pushdown(t[x << 1 | 1], t[x].lazy);
t[x].lazy = 0;
}//重载一下
void pushup(int x) {
t[x].val = t[x << 1].val + t[x << 1 | 1].val;
}//维护,不一定都是+,根据题目意思变化
void build(int l, int r, int x = 1) {
t[x] = { l, r, w[l], 0 };
if (l == r) return;
int mid = l + r >> 1;
build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1); //x<<1和x*2等价,x<<1|1和x*2=1等价
pushup(x);
}//二分建树
void modify(int l, int r, int c, int x = 1) {
if (l <= t[x].l && r >= t[x].r) { pushdown(t[x], c); return; }
pushdown(x);
int mid = t[x].l + t[x].r >> 1;
if (l <= mid) modify(l, r, c, x << 1);
if (r > mid) modify(l, r, c, x << 1 | 1);
pushup(x);
}//修改树
LL ask(int l, int r, int x = 1) {
if (l <= t[x].l && r >= t[x].r) return t[x].val;
pushdown(x);
int mid = t[x].l + t[x].r >> 1;
LL res = 0;
if (l <= mid) res += ask(l, r, x << 1);
if (r > mid) res += ask(l, r, x << 1 | 1);
return res;
}//询问区间
int main()
{
int n, m; cin >> n >> m;
rep(i, n) scanf("%d", &w[i]);
build(1, n);
while (m--) {
char op[2]; int l, r; scanf("%s %d %d", op, &l, &r);
if (*op == 'Q') printf("%lld\n", ask(l, r));
else {
int c; scanf("%d", &c);
modify(l, r, c);
}
}
return 0;
}