十万火急!!线段树求调
查看原帖
十万火急!!线段树求调
946114
DicaprioD楼主2024/10/24 20:19

距离下机还有半小时,各位大佬球球了

orz orz

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n,m;
int a[N],w[N * 4],lzy[N * 4];

void build(int id,int l,int r)
{
	if(l == r){
		w[id] = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(id << 1,l,mid);
	build(id << 1 | 1,mid + 1,r);
	
	w[id] = w[id << 1] + w[id << 1 | 1];
	return ;
}

void push_down(int id,int l,int r)
{
	if(lzy[id] == 0) return;
	lzy[id << 1] += lzy[id];
	lzy[id << 1 | 1] += lzy[id];
	int mid = (l + r) >> 1;
	w[id << 1] += (mid - l + 1) * lzy[id];
	w[id << 1 | 1] += (r - mid) * lzy[id];
	lzy[id] = 0; 
}

void update(int id,int l,int r,int L,int R,int c)
{
	if(l >=L && r <= R)
	{
		w[id] += (r - l + 1) *c;
		lzy[id] += c;
		return ;
	}
	push_down(id,l,r);
	int mid = (l + r) >> 1;
	if(R <= mid) update(id << 1,l,mid,L,R,c);
	else if(L > mid) update(id << 1 | 1,mid + 1,r,L,R,c);
	else update(id << 1,l,mid,L,mid,c),update(id << 1 | 1,mid + 1,r,mid + 1,R,c);
	w[id] = w[id << 1] + w[id << 1 | 1];
}

int find(int id,int l,int r,int L,int R)
{
	if(l >= L && r <= R)
	{
		return w[id];
	}
	push_down(id,l,r);
	int mid = (l + r) >> 1;
	if(R <= mid) find(id << 1,l,mid,L,R);
	else if(L > mid) find(id << 1 | 1,mid + 1,r,L,R);
	else find(id << 1,l,mid,L,mid) + find(id << 1 | 1,mid + 1,r,mid + 1,R);
}

signed main()
{
	int n,m;
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n; ++ i)
		scanf("%lld",&a[i]);
	build(1,1,n);
	while(m --)
	{
		int op,l,r,c;
		scanf("%lld",&op);
		if(op == 1)
		{
			scanf("%lld%lld%lld",&l,&r,&c);
			update(1,1,n,l,r,c);
		}
		if(op == 2)
		{
			scanf("%lld%lld",&l,&r);
			cout << find(1,1,n,l,r) << endl;
		}
	}
}
2024/10/24 20:19
加载中...