线段树

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int long long
int n,m,mod;
struct tree{
	int l,r,sum,mul,add;//mul 初始1 add 初始0 ! 
}tr[100005*4]; 
int a[100005];
void pushup(int p)
{
	tr[p].sum=(tr[p<<1].sum+tr[p<<1|1].sum);
}
void eval(tree &t,int mul,int add)//先乘后加
{
	t.sum=((ll)t.sum*mul+(ll)(t.r-t.l+1)*add);
	t.mul=((ll)t.mul*mul);
	t.add=((ll)t.add*mul+add);
} 
void pushdown(int p)
{
	eval(tr[p<<1],tr[p].mul,tr[p].add);
	eval(tr[p<<1|1],tr[p].mul,tr[p].add);
	tr[p].mul=1;tr[p].add=0;//重置! 
}
void build(int p,int l,int r)
{
	if(l==r)
	{
		tr[p]={l,r,a[l],1,0};
		return ;
	}
	tr[p]={l,r,0,1,0};//1! 
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
}

void modify(int p,int l,int r,int mul,int add)
{
	if(l<=tr[p].l&&r>=tr[p].r)
	{
		eval(tr[p],mul,add);
		return ;
	}	
	pushdown(p);
	int mid=(tr[p].l+tr[p].r)>>1;
	if(l<=mid)modify(p<<1,l,r,mul,add);
	if(r>mid)modify(p<<1|1,l,r,mul,add);
	pushup(p);
} 
int query(int p,int l,int r)
{
	
	if(l<=tr[p].l&&r>=tr[p].r)
	{
		return tr[p].sum;
	}
	pushdown(p);
	int mid=(tr[p].l+tr[p].r)>>1;
	int sum=0;
	if(l<=mid)sum+=query(p<<1,l,r);
	if(r>mid)sum=(sum+query(p<<1|1,l,r));
	return sum;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int op,x,y,k;
		cin>>op;
		if(op==1)
		{
			cin>>x>>y>>k;
			modify(1,x,y,1,k);
		}
		if(op==2)
		{
			cin>>x>>y;
			cout<<query(1,x,y)<<endl;
		}
	}
	return 0;
}

posted @ 2023-01-03 13:27  PKU_IMCOMING  阅读(13)  评论(0)    收藏  举报