0ptsWA求调
查看原帖
0ptsWA求调
214927
ZOU_S楼主2024/12/3 16:14

rt

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5+5;
int t[N*4], a[N], alazy[N*4], mlazy[N*4]; // 加懒标记 和 乘懒标记 
int n, q, p; // 数列大小,操作次数,取模数 

void push_up(int id)
{
	t[id] = t[id << 1] + t[id << 1 | 1] % p;
}

void build(int id, int l, int r)
{
	alazy[id] = 0, mlazy[id] = 1;
	if(l == r)
	{
		t[id] = a[l] % p;
		return ;
	}
	
	int mid = l + r >> 1;
	build(id << 1, l , mid);
	build(id << 1 | 1, mid + 1 , r);
	
	push_up(id);
}
void apushdown(int id, int l, int r, int mid)//加懒标记下放操作 
{
	//左子节点 
	t[id<<1] = (t[id<<1] + (mid - l + 1) * alazy[id]) % p;
	alazy[id<<1] = (alazy[id<<1]+alazy[id]) % p;
	
	t[id<<1|1] = (t[id<<1|1] + (r - mid) * alazy[id]) % p;
	alazy[id<<1|1] = (alazy[id<<1|1] + alazy[id]) % p;
	
	alazy[id] = 0;
	
}
void mpushdown(int id, int l, int r, int mid)
{
	t[id<<1] = (t[id<<1] * mlazy[id]) % p;
	mlazy[id<<1] = (mlazy[id<<1] * mlazy[id]) % p;
	alazy[id<<1] = (alazy[id<<1] * mlazy[id]) % p;		//记得同时维护加懒标记
	
	t[id<<1|1] = (t[id<<1|1] * mlazy[id]) % p;
	mlazy[id<<1|1] = (mlazy[id<<1|1] * mlazy[id]) % p;
	alazy[id<<1|1] = (alazy[id<<1|1] * mlazy[id]) % p;
	
	mlazy[id] = 1;//乘法重置为1 
	 
}
void pushdown(int id, int l, int r, int mid)
{
	//先乘后加 
	mpushdown(id, l, r, mid);
	apushdown(id, l, r, mid);
}
int query(int id, int l, int r, int x, int y)//询问 
{
	if(x <= l && y >= r) return t[id];//若询问区间内包含结果 
	int mid = l + r >> 1, res = 0;
	pushdown(id, l, r, mid);
	if(x <= mid) res =(res + query(id<<1|1,l,mid,x,y)) % p;             // 包含左子区间
    if(y > mid) res = res + query(id<<1|1,mid+1,r,x,y) % p; // 包含右子区间
    return res % p; // 返回
}
void add(int id, int l, int r, int x, int y, int v)//加法运算 
{
	if(x <= l && y >= r)
	{
		t[id] = (t[id] + (r - l + 1) * v) % p;//父节点赋值,每个子节点的v都加一遍
		alazy[id] = (alazy[id] + v) % p; //懒标记更新
		return ; 
	}
	
	int mid = l + r >> 1;
	pushdown(id, l, r, mid);
	if(x <= mid) add(id<<1, l, mid, x, y, v);
	if(y > mid) add(id<<1|1, mid + 1, r, x, y, v);
	
	push_up(id); 
}
void mul(int id, int l, int r, int x, int y, int v)//乘法运算 
{
	if(x <= l && y >= r)
	{
		t[id] = (t[id] * v) % p;//父节点赋值,每个子节点的v都加一遍
		alazy[id] = (alazy[id] * v) % p; //懒标记更新
		mlazy[id] = (mlazy[id] * v) % p;
		return ; 
	}
	
	int mid = l + r >> 1;
	pushdown(id, l, r, mid);
	if(x <= mid) mul(id<<1, l, mid, x, y, v);
	if(y > mid) mul(id<<1|1, mid + 1, r, x, y, v);
	
	push_up(id); 
}
int main()
{
	cin >> n >> q >> p;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	build(1, 1, n);
	while(q--)
	{
		int op, x, y, k;
		cin >> op >> x >> y;
		if (op == 1)
		{
			cin >> k;
			mul(1, 1, n, x, y, k);
		}
		else if(op == 2)
		{
			cin >> k;
			add(1, 1, n, x, y, k);
		}
		else
		{
			int ans = query(1, 1, n, x, y);
			cout << ans << endl;
		}
	}
	return 0;
} 
2024/12/3 16:14
加载中...