太久没写线段树就想着写一个模板结果挂了,和以前的代码比较也看不出来错。
//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef int ll;
int n,m,a[100010],p[400010],tree[400010];
inline ll read(){
ll x = 0,m = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch=='-') m = -1;
ch = getchar();
}
while(isdigit(ch)){
x = x * 10 + ch - 48;
ch = getchar();
}
return x * m;
}
inline void write(ll x){
if(x < 0){
putchar('-');
write(-x);
return;
}
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
inline void jf(int sum){
tree[sum] = tree[sum * 2] + tree[sum * 2 + 1];
}
inline void build(int l,int r,int sum){
if(l == r){
tree[sum] = a[l];
return;
}
int mid = (l + r) / 2;
build(l,mid,sum * 2);
build(mid + 1,r,sum * 2 + 1);
jf(sum);
}
inline void pushdown(int l,int r,int sum){
p[sum * 2] += p[sum];
p[sum * 2 + 1] += p[sum];
int mid = (l + r) / 2;
tree[sum * 2] += p[sum] * (mid - l + 1);
tree[sum * 2 + 1] += p[sum] * (r - mid);
p[sum] = 0;
}
inline void add(int l,int r,int x,int y,int sum,int k){
if(l == x && r == y){
tree[sum] += k * (r - l + 1);
p[sum] += k;
return;
}
int mid = (l + r) / 2;
pushdown(l,r,sum);
if(x <= mid && y > mid){
add(l,mid,x,mid,sum * 2,k);
add(mid + 1,r,mid + 1,y,sum * 2 + 1,k);
}
else if(x <= mid){
add(l,mid,x,y,sum * 2,k);
}
else{
add(mid + 1,r,x,y,sum * 2 + 1,k);
}
jf(sum);
}
inline int query(int l,int r,int x,int y,int sum){
if(l == x && r == y){
return tree[sum];
}
int mid = (l + r) / 2;
if(x <= mid && y > mid){
return query(l,mid,x,mid,sum * 2) + query(mid + 1,r,mid + 1,y,sum * 2 + 1);
}
else if(x <= mid){
return query(l,mid,x,y,sum * 2);
}
else{
return query(mid + 1,r,x,y,sum * 2 + 1);
}
}
signed main(){
n = read(), m = read();
for(int i = 1; i <= n; ++ i) a[i] = read();
build(1,n,1);
while(m --){
int c = read();
if(c == 1){
int x = read(), y = read(), z = read();
add(1,n,x,y,1,z);
}
else{
int x = read(), y = read();
write(query(1,n,x,y,1)),putchar('\n');
}
}
return 0;
}