注意size信息应该存放在info里和tag运算,已经tag是表示子树未处理的信息

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
const int N = 1e5+10;
int n,m;
int a[N];
struct info
{
	ll sum,sz;
};
struct tag
{
	ll add;
};
//处理左右子树
info operator + (const info &l,const info &r)
{
	return {l.sum + r.sum, l.sz + r.sz};
}
//处理节点和标记的作用
info operator + (const info &v,const tag &t)
{
	return {v.sum + t.add*v.sz, v.sz};
}
//处理lazy标记的传递t1作用于t2
tag operator + (const tag &t1, const tag &t2)
{
	return {t1.add + t2.add};
}
struct node
{
	int l,r;
	info val;
	tag t;
}tr[N<<2];

//settag是在pushdown里面用表示用tagt更新p点
void settag(int p,tag t)
{
	//注意tag表示的是下面的区段未更新的值,settag当前p应该由t更新
	tr[p].val = tr[p].val + t;
	tr[p].t = t + tr[p].t;
}
void pushup(int p)
{
	tr[p].val = tr[p<<1].val + tr[p<<1|1].val;
}
void pushdown(int p)
{
	auto &t = tr[p].t;
	if(t.add)
	{
		settag(p<<1,t);
		settag(p<<1|1,t);
		t.add = 0;
	}
}
void build(int l,int r,int p)
{
	tr[p].l = l, tr[p].r = r;
	if(l == r) 
	{
		tr[p].val = {a[r],1};
		return ;
	}
	int m = (l+r)/2;
	build(l,m,p<<1);
	build(m+1,r,p<<1|1);
	pushup(p);
}
void update(int L,int R,tag C,int p)
{
	int l = tr[p].l, r = tr[p].r;
	if(L<=l&&r<=R) 
	{
		settag(p,C);
		return ;
	}
	pushdown(p);
	int m = (l+r)/2;
	if(R<=m) update(L,R,C,p<<1);
	else if(L>m) update(L,R,C,p<<1|1);
	else 
	{
		update(L,m,C,p<<1);
		update(m+1,R,C,p<<1|1);
	}
	pushup(p);
}
info query(int L,int R,int p)
{
	int l = tr[p].l, r = tr[p].r;
	if(L<=l&&r<=R) return tr[p].val;
	pushdown(p);
	int m = (l+r)/2;
	if(R<=m) return query(L,R,p<<1);
	else if(L>m) return query(L,R,p<<1|1);
	else return query(L,m,p<<1) + query(m+1,R,p<<1|1);
}

void solve()
{
    cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	build(1,n,1);
	for(int i=0;i<m;++i)
	{
		int op,l,r,x;
		cin>>op;
		if(op&1)
		{
			cin>>l>>r>>x;
			update(l,r,tag{x},1);
		}
		else
		{
			cin>>l>>r;
			cout<<query(l,r,1).sum<<'\n';
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T = 1;
	//cin>>T;
	while(T--)
	{
		solve();
	}
}
 posted on 2024-09-29 16:35  ruoye123456  阅读(2)  评论(0编辑  收藏  举报