返回顶部

洛谷 P3372 【模板】线段树 1

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;

int n,m;
int a[N];
int l,r,x;

struct Node{
	int l,r;
	ll sum,add;
}tr[N<<2];

void push_up(int u){
	tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}

void push_down(int u){
	auto &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
	if(root.add){
		left.add+=root.add,left.sum+=(ll)(left.r-left.l+1)*root.add;
		right.add+=root.add,right.sum+=(ll)(right.r-right.l+1)*root.add;
		root.add=0;
	}
}

void build(int u,int l,int r){
	if(l==r) tr[u]={l,r,a[r],0};
	else{
		tr[u]={l,r,0,0};
		int mid=(l+r)>>1;
		build(u<<1,l,mid);
		build(u<<1|1,mid+1,r);
		push_up(u);
	}	
}

void modify(int u,int l,int r,int d){
	if(tr[u].l>=l && tr[u].r<=r){
		tr[u].sum+=(ll)(tr[u].r-tr[u].l+1)*d;
		tr[u].add+=d;
	}
	else{
		push_down(u);
		int mid=(tr[u].l+tr[u].r)>>1;
		if(l<=mid) modify(u<<1,l,r,d);
		if(r>mid) modify(u<<1|1,l,r,d);
		push_up(u);
	}
}

ll query(int u,int l,int r){
	if(tr[u].l>=l && tr[u].r<=r) return tr[u].sum;
	
	push_down(u);

	int mid=(tr[u].l+tr[u].r)>>1;
	ll sum=0;
	if(l<=mid) sum=query(u<<1,l,r);
	if(r>mid) sum+=query(u<<1|1,l,r);

	return sum;
}

int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;

	rep(i,1,n) cin>>a[i];

	build(1,1,n);

	while(m--){
		int op;
		cin>>op;
		if(op==1){
			cin>>l>>r>>x;
			modify(1,l,r,x);
		}
		else{
			cin>>l>>r;
			cout<<query(1,l,r)<<'\n';
		}
	}

    return 0;
}
```cpp
posted @ 2020-12-07 13:40  Rayotaku  阅读(90)  评论(0编辑  收藏  举报