洛谷P3372 【模板】线段树 1

题链

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define MS 100009
#define INF 20000009
#define mod 1000000007
#define Pi acos(-1.0)
#define Pair pair<LL,LL>

LL n,m,k;
LL p[MS<<2];
LL la[MS<<2];

bool in(int L,int l,int r,int R){
	return (l<=r) && (L<=l) && (r<=R); 
} 

void push_up(int rt){
	p[rt] = p[ls] + p[rs];
}

void push_down(int rt,int l,int r){
	if(la[rt]){
		int m = l+r >> 1;
		p[ls] += la[rt]*(m-l+1);
		p[rs] += la[rt]*(r-m);
		la[ls] += la[rt];
		la[rs] += la[rt];
		la[rt] = 0;
	}
}

void update(int L,int R,int l,int r,int rt,LL val){
	if(in(L,l,r,R)){
		p[rt] += (r-l+1)*val;
		la[rt] += val;
		return;
	}
	push_down(rt,l,r);
	int m = l+r>>1;
	if(m >= L) update(L,R,l,m,ls,val);
	if(m <  R) update(L,R,m+1,r,rs,val);
	push_up(rt);
}

LL get_sum(int L,int R,int l,int r,int rt){
	if(in(L,l,r,R)){
		return p[rt];
	}
	push_down(rt,l,r);
	LL cc = 0;
	int m = l+r>>1;
	if(m >= L) cc += get_sum(L,R,l,m,ls);
	if(m <  R) cc += get_sum(L,R,m+1,r,rs);
	return cc;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		LL x;
		cin >> x;
		update(i,i,1,n,1,x);
	}
	while(m--){
		LL op,l,r,val;
		cin >> op >> l >> r;
		if(op == 2){
			LL ans = get_sum(l,r,1,n,1);
			cout << ans << endl;
		}
		else if(op == 1){
			cin >> val;
			update(l,r,1,n,1,val);
		}
	}
	

	return 0;
}
posted @ 2021-02-16 23:45  棉被sunlie  阅读(22)  评论(0)    收藏  举报