空间已经开了4倍,不知道哪里错了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 9;
int a[N],n,m;
namespace SegmentTree {
struct Seg {
int l,r;
ll pre,lazy;
}Tree[N * 4];
inline int lchild(int root) {
return root * 2;
}
inline int rchild(int root) {
return root * 2 + 1;
}
void build(int root,int l,int r) {
Tree[root].l = l;Tree[root].r = r;
if(l == r) {
Tree[root].pre = a[l];
return;
}
int mid = (l + r) >> 1;
build(lchild(root),l,mid);
build(rchild(root),mid + 1,r);
Tree[root].pre = Tree[lchild(root)].pre + Tree[rchild(root)].pre;
}
void push_down(int root) {
if(Tree[root].lazy) {
Tree[lchild(root)].pre += Tree[root].lazy * (Tree[lchild(root)].r - Tree[lchild(root)].l + 1);
Tree[rchild(root)].pre += Tree[root].lazy * (Tree[rchild(root)].r - Tree[rchild(root)].l + 1);
Tree[lchild(root)].lazy += Tree[root].lazy;
Tree[rchild(root)].lazy += Tree[root].lazy;
Tree[root].lazy = 0;
}
}
void upload(int root,int l,int r,ll k) {
if(Tree[root].l >= l && Tree[root].r <= r) {
Tree[root].pre += k * (Tree[root].r - Tree[root].l + 1);
Tree[root].lazy += k;
return;
}
push_down(root);
int mid = (Tree[root].l + Tree[root].r) >> 1;
if(l <= mid) upload(lchild(root),l,r,k);
if(r > mid) upload(rchild(root),l,r,k);
Tree[root].pre = Tree[lchild(root)].pre + Tree[rchild(root)].pre;
}
ll query(int root,int l,int r) {
if(Tree[root].l >= l && Tree[root].r <= r) {
return Tree[root].pre;
}
push_down(root);
ll ans = 0;
int mid = (l + r) >> 1;
if(l <= mid) ans += query(lchild(root),l,r);
if(r > mid) ans += query(rchild(root),l,r);
return ans;
}
};
using namespace SegmentTree;
template<class T>
inline void read(T& x) {
x = 0;
int f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
x *= f;
}
int main() {
read(n);read(m);
for(int i = 1;i <= n;i++) {
read(a[i]);
}
build(1,1,n);
for(int i = 1;i <= m;i++) {
int opt;
read(opt);
switch(opt) {
case 1: {
int l,r;ll k;
read(l);read(r);read(k);
upload(1,l,r,k);
break;
}
case 2: {
ll k;
read(k);
upload(1,1,1,k);
break;
}
case 3: {
ll k;
read(k);
upload(1,1,1,-k);
break;
}
case 4: {
int l,r;
read(l);read(r);
printf("%lld\n",query(1,l,r));
break;
}
case 5: {
printf("%lld\n",query(1,1,1));
break;
}
}
}
return 0;
}