其他分享
首页 > 其他分享> > P3372 【模板】线段树 1

P3372 【模板】线段树 1

作者:互联网

https://www.luogu.org/problemnew/show/P3372

#include <iostream>
#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;

const int MAXN=400005;
int n,m,x,u,v;
ll k,jl[MAXN];
struct cyq{
	int l,r;
	ll num,tip;
}a[MAXN];

void build(int p,int l,int r){
	a[p].l=l;a[p].r=r;
	if(l==r) {a[p].num=jl[l];return;}
	int mid=(l+r)>>1;
	build(p*2,l,mid);build(p*2+1,mid+1,r);
	a[p].num=a[p*2].num+a[p*2+1].num;
}

void spread(int p){
	if(a[p].tip==0) return;
	a[p*2].num+=a[p].tip*(a[p*2].r-a[p*2].l+1);
	a[p*2+1].num+=a[p].tip*(a[p*2+1].r-a[p*2+1].l+1);
	a[p*2].tip+=a[p].tip;a[p*2+1].tip+=a[p].tip;
	a[p].tip=0;
}

void change(int p){
	if(u<=a[p].l && v>=a[p].r){
		a[p].num+=(ll)k*(a[p].r-a[p].l+1);
		a[p].tip+=k;return;
	}spread(p);
	int mid=(a[p].l+a[p].r)>>1;
	if(u<=mid) change(p*2);
	if(v>mid) change(p*2+1);
	a[p].num=a[p*2].num+a[p*2+1].num;
}

ll ask(int p)
{
	if(u<=a[p].l && v>=a[p].r) return a[p].num;
	spread(p);long long ans=0;
	int mid=(a[p].l+a[p].r)>>1;
	if(u<=mid) ans+=ask(p*2);
	if(v>mid) ans+=ask(p*2+1);
	return ans;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&jl[i]);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%d",&x);
		if(x==1) {
			scanf("%d%d%lld",&u,&v,&k);
			change(1);
		}
		if(x==2) {
			scanf("%d%d",&u,&v);
			printf("%lld\n",ask(1));
		}
	}
	return 0;
}

标签:return,int,线段,tip,mid,num,P3372,ll,模板
来源: https://blog.csdn.net/hssl_ywl/article/details/96428886