说白了动态开点就是用两个整型变量存子节点。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e5+10;
int a[maxn],cnt;
struct node{
int ls,rs,k;
}t[maxn<<4];
void Insert(int l,int r,int pos,int val,int now){
if(l == r) {
t[cnt].k= val;
return ;
}
int mid = (l+r)>>1;
if(pos<=mid){
if(t[now].ls == 0) {
t[++cnt].k = 0;
t[cnt].ls = 0;
t[cnt].rs = 0;
t[now].ls = cnt;
}
Insert(l,mid,pos,val,t[now].ls);
}
else {
if(t[now].rs == 0){
t[++cnt].k = 0;
t[cnt].ls = 0;
t[cnt].rs = 0;
t[now].rs = cnt;
}
Insert(mid + 1, r, pos, val,t[now].rs);
}
t[now].k = t[t[now].rs].k + t[t[now].ls].k;
}
int lazy[maxn << 4];
int pushdown(int now,int l,int r){
int mid = (l+r)>>1;
t[t[now].ls].k +=(mid - l + 1) * lazy[now];
t[t[now].rs].k +=(r - mid)* lazy[now];
lazy[t[now].ls] += lazy[now];
lazy[t[now].rs] += lazy[now];
lazy[now] = 0 ;
}
void update(int l,int r,int L,int R,int v,int now){
if (l >= L && r <= R){
t[now].k += v * (r - l + 1);
lazy[now] += v;
return;
}
pushdown(now,l,r);
int mid = (l+r)>>1;
if (L <= mid){
update(l,mid,L,R,v,t[now].ls);
}
if(R>mid){
update(mid+1,r,L,R,v,t[now].rs);
}
t[now].k = t[t[now].ls].k + t[t[now].rs].k;
}
int query(int l,int r,int L,int R,int now){
int res = 0;
if(l>=L&&r<=R){
return t[now].k;
}
pushdown(now,l,r);
int mid = (l+r)>>1;
if(L<=mid){
res += query(l,mid,L,R,t[now].ls);
}
if(R>mid){
res += query(mid + 1,r, L,R,t[now].rs);
}
return res;
}
signed main() {
int n,m;
cin>>n>>m;
cnt = 1;
for(int i=1;i<=n;i++){
cin>>a[i];
Insert(1,maxn,i,a[i],1);
}
for(int i=1;i<=m;i++){
int ty;
cin>>ty;
int x,y,k;
if(ty == 1){
cin>>x>>y>>k;
update(1,maxn,x,y,k,1);
}
if(ty == 2){
cin>>x>>y;
cout<<query(1,maxn,x,y,1)<<endl;
}
}
return 0;
}