200字
「模板」线段树
2025-11-28
2025-11-28
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[1145141],n,m;
struct node{
	int sum[1145141];
	int tag[1145141];
	void build(int l=1,int r=n,int p=1) {
		if(l==r) {
			sum[p]=a[l];
			return;
		}
		build(l,(l+r)/2,p*2);
		build((l+r)/2+1,r,p*2+1);
		sum[p]=sum[p*2]+sum[p*2+1];
		return;
	}
	void push_down(int p,int l,int r) {
		if(tag[p]==0) return;
		int mid=(l+r)/2;
		int lenL=mid-l+1;
		int lenR=r-mid;
		sum[p*2]+=tag[p]*lenL;
		tag[p*2]+=tag[p];
		sum[p*2+1]+=tag[p]*lenR;
		tag[p*2+1]+=tag[p];
		tag[p]=0;
		return;
	}
	void add(int li,int ri,int k,int l=1,int r=n,int p=1) {
		if(li<=l and ri>=r) {
			sum[p]+=k*(r-l+1);
			tag[p]+=k;
			return;
		}
		push_down(p,l,r);
		int mid=(l+r)/2;
		if(li<=mid) add(li,ri,k,l,mid,p*2);
		if(ri>mid) add(li,ri,k,mid+1,r,p*2+1);
		sum[p]=sum[p*2]+sum[p*2+1];
		return;
	}
	int query(int li,int ri,int l=1,int r=n,int p=1) {
		if(li<=l and ri>=r) {
			return sum[p];
		}
		push_down(p,l,r);
		int mid=(l+r)/2,res=0;
		if(li<=mid) res+=query(li,ri,l,mid,p*2);
		if(ri>mid) res+=query(li,ri,mid+1,r,p*2+1);
		return res;
	}
}tr;
signed main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	int x,y,z,q;
	tr.build();
	for(int i=1;i<=m;i++) {
		cin>>x;
		if(x==1) {
			cin>>y>>z>>q;
			tr.add(y,z,q);
		}
		else {
			cin>>y>>z;
			cout<<tr.query(y,z)<<"\n";
		}
	}
	return 0;
}