玄关求调
查看原帖
玄关求调
1098596
WhiteNight__楼主2024/6/6 13:55
#include <iostream>
#include <cstdio>

using namespace std;

#define ll long long
#define Mod(x) ((x) %= m)

struct Tree {
	int l , r;
	ll pre , add , mul;
}t[600050];

ll n , m , q , op , x , y , k , a[100050];

inline void unionn (int num)
{
	t[num].pre = t[num*2].pre + t[num*2+1].pre;
	Mod(t[num].pre);
	return;
}

inline void f (int num , ll addx , ll mulx)
{
	t[num].pre = (t[num].pre * mulx % m + addx * (t[num].r - t[num].l + 1) % m);
	t[num].add = t[num].add * mulx + addx;
	t[num].mul *= mulx;
	Mod(t[num].pre);
	Mod(t[num].mul);
	Mod(t[num].add);
	return;
}

inline void down (int num)
{
	f(num*2 , t[num].add , t[num].mul);
	f(num*2+1 , t[num].add , t[num].mul);
	t[num].add = 0;
	t[num].mul = 1;
	return;
}

void update_add (int num , int L , int R , ll x)
{
	const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
	if(L <= l && R >= r)
	{
		t[num].pre += (r-l+1) * x;
		t[num].add += x;
		Mod(t[num].pre);
		Mod(t[num].add);
		return;
	}
	down (num);
	
	if(L <= mid)
		update_add(num*2 , L , R , x);
	if(R >= mid+1)
		update_add(num*2+1 , L , R , x);
	unionn (num);
	return;
}

void update_mul (int num , int L , int R , ll x)
{
	const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
	if(L <= l && R >= r)
	{
		t[num].pre *= x;
		t[num].add *= x;
		t[num].mul *= x;
		Mod(t[num].pre);
		Mod(t[num].add);
		Mod(t[num].mul);
		return;
	}
	
	down (num);
	
	if(L <= mid)
		update_add(num*2 , L , R , x);
	if(R >= mid+1)
		update_add(num*2+1 , L , R , x);
	unionn (num);
	return;
}

ll sum (int num , int L , int R)
{
	const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
	if(L <= l && R >= r)
		return t[num].pre % m;
	down(num);
	ll ans = 0;
	if(L <= mid)
		ans += sum (num*2 , L , R);
	if(R >= mid+1)
		ans += sum (num*2+1 , L , R);
	return ans % m;
}

void build (int num , int L , int R)
{
	t[num].l = L , t[num].r = R , t[num].mul = 1 , t[num].add = 0;
	if(L == R)
	{
		t[num].pre = a[L] % m;
		return;
	}
	int mid = (L+R) >> 1;
	build(num*2 , L , mid);
	build(num*2+1 , mid+1 , R);
	unionn(num);
	return;
}

int main()
{
	scanf("%lld%lld%lld",&n,&q,&m);
	
	for(int i = 1 ; i <= n ; i ++)
		scanf("%lld",&a[i]);
	
	build (1 , 1 , n);
	
	while (q --)
	{
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op == 1)
		{
			scanf("%lld",&k);
			Mod(k);
			update_mul(1,x,y,k);
		}
		else if(op == 2)
		{
			scanf("%lld",&k);
			Mod(k);
			update_add(1,x,y,k);
		}
		else{
			printf("%lld\n",sum(1,x,y)%m);
		}
	}
	
	
	return 0;
}
2024/6/6 13:55
加载中...