萌新刚学线段树求助!!玄关
  • 板块灌水区
  • 楼主ChenZQ
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/8/30 16:26
  • 上次更新2023/11/3 00:20:11
查看原帖
萌新刚学线段树求助!!玄关
745358
ChenZQ楼主2023/8/30 16:26

https://www.luogu.com.cn/problem/P3372

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
struct node
{
	int l,r,pre,add;
};

node t[100010];
int b[100010];

void build(int l,int r,int u)
{
	t[u].l=l,t[u].r=r;
	if(l==r)
	{
		t[u].pre=b[l];
		return;
	}
	int mid=(t[u].l+t[u].r)>>1;
	build(l,mid,2*u);
	build(mid+1,r,2*u+1);
	t[u].pre=t[2*u].pre+t[2*u+1].pre;
}
void spread(int u)
{
	if(t[u].add>0)
	{
		t[2*u].pre+=t[u].add*(t[2*u].r-t[2*u].l+1);
		t[2*u+1].pre+=t[u].add*(t[2*u+1].r-t[2*u+1].l+1);
		t[2*u].add+=t[u].add; 
		t[2*u+1].add+=t[u].add;
		t[u].add=0;
	}
}
void change(int u,int l,int r,int z)
{
	if(l<=t[u].l && r>=t[u].r)
	{
		t[u].pre+=z*(t[u].r-t[u].l+1);
		t[u].add=z;
		return; 
	}
	spread(u);
	int mid=t[u].l+t[u].r>>1;
	if(l<=mid) change(2*u,l,r,z);
	if(r>mid) change(2*u+1,l,r,z);
	t[u].pre=t[u*2].pre+t[u*2+1].pre;
}
int ask(int u,int l,int r)
{
	if(l<=t[u].l && r>=t[u].r) return t[u].pre;
	spread(u);
	int ans=0;
	int mid=t[u].l+t[u].r>>1;
	if(l<=mid) ans+=ask(2*u,l,r);
	if(r>mid) ans+=ask(2*u+1,l,r);
	return ans;
}
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
	build(1,n,1);
	while(m--)
	{
		int op,x,y,z;
		scanf("%lld",&op);
		if(op==1)
		{
			scanf("%lld%lld%lld",&x,&y,&z);
			change(1,x,y,z);
		}
		else
		{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",ask(1,x,y));
		}
	}
}
2023/8/30 16:26
加载中...