在线等,线段树模板题,就过一点QWQ
  • 板块学术版
  • 楼主Main_WF
  • 当前回复22
  • 已保存回复22
  • 发布时间2020/7/28 19:36
  • 上次更新2023/11/6 21:56:18
查看原帖
在线等,线段树模板题,就过一点QWQ
302750
Main_WF楼主2020/7/28 19:36
#include<bits/stdc++.h>
#define maxn 100000+10
using namespace std;

struct node
{
	int l,r,sum,lazy;
}t[maxn];

int n,a[maxn];

void build(int id,int l,int r)
{
	t[id].l=l;
	t[id].r=r;
	if(l==r)
	{
		t[id].sum=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	t[id].sum=t[id*2].sum+t[id*2+1].sum;
}

void down(int id)
{
	t[2*id].lazy=t[id].lazy;
	t[2*id+1].lazy=t[id].lazy;//父亲的懒标记下传
	t[2*id].sum+=t[id].lazy*(t[2*id].r-t[2*id].l+1) ;
	t[2*id+1].sum+=t[id].lazy*(t[2*id+1].r-t[2*id+1].l+1) ;
	t[id].lazy=0;
}

void update(int id,int l,int r,int x)
{
	if(t[id].l==l&&t[id].r==r)//一整块区间,直接lazy标记 
	{
		t[id].lazy+=x;
		t[id].sum+=(t[id].r-t[id].l+1)*t[id].lazy;//计算真实区间值 
		return ;
	}
	if(t[id].lazy)down(id);
	int mid=(t[id].l+t[id].r)/2;
	if(r<=mid)update(id*2,l,r,x);
	else if(l>mid)update(id*2+1,l,r,x);
	else 
	{
		update(id*2,l,mid,x);
		update(id*2+1,mid+1,r,x);
	}
	t[id].sum=t[id*2].sum+t[id*2+1].sum;
}

int query(int id,int l,int r)
{
	if(t[id].l==l&&t[id].r==r)
	{
		return t[id].sum;
	}
	if(t[id].lazy)down(id);
	int temp=0;
	int mid=(t[id].l+t[id].r)/2;
	if(r<=mid)temp+=query(id*2,l,r);
	else if(l>mid)temp+=query(id*2+1,l,r);
	else temp+=query(id*2,l,mid)+query(id*2+1,mid+1,r);
	return temp;
}

int main()
{
	int c;
	cin>>n;
	cin>>c;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=c;i++)//查询字符 
	{
		char ch;//查询类型
		cin>>ch;
		if(ch=='1')
		{
			int tl,tr,x;//将[tl,tr]区间的数加上x 
			cin>>tl>>tr>>x;
			update(1,tl,tr,x);
		}
		if(ch=='2')//查询区间和 
		{
			int tl,tr;
			cin>>tl>>tr;
			cout<<query(1,tl,tr)<<'\n';
		}
	}
}

2020/7/28 19:36
加载中...