luogu2023 [AHOI2009]维护序列

线段树加乘懒标记裸题。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, mod, m, t, u, v;
ll w;
struct SGT{
	ll sum[400005];
	ll lzt[400005];
	ll mul[400005];
	void built(int o, int l, int r){
		lzt[o] = 0;
		mul[o] = 1;
		if(l==r)	scanf("%lld", &sum[o]);
		else{
			int mid=(l+r)>>1;
			int lson=o<<1;
			int rson=lson|1;
			if(l<=mid)	built(lson, l, mid);
			if(mid<r)	built(rson, mid+1, r);
			sum[o] = (sum[lson] + sum[rson]) % mod;
		}
	}
	void push_down(int o, int l, int r, int lson, int rson, int mid){
		mul[lson] = (mul[o] * mul[lson]) % mod;
		mul[rson] = (mul[o] * mul[rson]) % mod;
		lzt[lson] = (mul[o] * lzt[lson]) % mod;
		lzt[rson] = (mul[o] * lzt[rson]) % mod;
		sum[lson] = (mul[o] * sum[lson]) % mod;
		sum[rson] = (mul[o] * sum[rson]) % mod;
		mul[o] = 1;
		lzt[lson] = (lzt[o] + lzt[lson]) % mod;
		lzt[rson] = (lzt[o] + lzt[rson]) % mod;
		sum[lson] = (sum[lson] + (mid-l+1) * lzt[o]) % mod;
		sum[rson] = (sum[rson] + (r-mid) * lzt[o]) % mod;
		lzt[o] = 0;
	}
	void update_add(int o, int l, int r, int x, int y, ll k){
		if(l>=x && r<=y){
			sum[o] = (sum[o] + (r-l+1) * k) % mod;
			lzt[o] = (lzt[o] + k) % mod;
		}
		else{
			int mid=(l+r)>>1;
			int lson=o<<1;
			int rson=lson|1;
			if(mul[o]!=1 || lzt[o])	push_down(o, l, r, lson, rson, mid);
			if(x<=mid)	update_add(lson, l, mid, x, y, k);
			if(mid<y)	update_add(rson, mid+1, r, x, y, k);
			sum[o] = (sum[lson] + sum[rson]) % mod;
		}
	}
	void update_mul(int o, int l, int r, int x, int y, ll k){
		if(l>=x && r<=y){
			mul[o] = (mul[o] * k) % mod;
			lzt[o] = (lzt[o] * k) % mod;
			sum[o] = (sum[o] * k) % mod;
		}
		else{
			int mid=(l+r)>>1;
			int lson=o<<1;
			int rson=lson|1;
			if(mul[o]!=1 || lzt[o])	push_down(o, l, r, lson, rson, mid);
			if(x<=mid)	update_mul(lson, l, mid, x, y, k);
			if(mid<y)	update_mul(rson, mid+1, r, x, y, k);
			sum[o] = (sum[lson] + sum[rson]) % mod;
		}
	}
	ll query(int o, int l, int r, int x, int y){
		if(l>=x && r<=y)	return sum[o];
		else{
			int mid=(l+r)>>1;
			int lson=o<<1;
			int rson=lson|1;
			ll ans=0;
			if(mul[o]!=1 || lzt[o])	push_down(o, l, r, lson, rson, mid);
			if(x<=mid)	ans = (ans + query(lson, l, mid, x, y)) % mod;
			if(mid<y)	ans = (ans + query(rson, mid+1, r, x, y)) % mod;
			return ans;
		}
	}
}sgt;
int main(){
	cin>>n>>mod;
	sgt.built(1, 1, n);
	cin>>m;
	while(m--){
		scanf("%d", &t);
		if(t==1){
			scanf("%d %d %lld", &u, &v, &w);
			sgt.update_mul(1, 1, n, u, v, w);
		}
		else if(t==2){
			scanf("%d %d %lld", &u, &v, &w);
			sgt.update_add(1, 1, n, u, v, w);
		}
		else{
			scanf("%d %d", &u, &v);
			printf("%lld
", sgt.query(1, 1, n, u, v));
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/7865617.html