悬赏关注,样例不过求调
查看原帖
悬赏关注,样例不过求调
915245
editor_1楼主2023/12/31 17:37
// Problem: 
//     P3373 【模板】线段树 2
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3373
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int  N = 2e6 + 10;
int times;
int n,q,mod; 
int arr[N],d[N],b1[N],b2[N];
void push(int m,int s,int t,int p)
{
	d[p*2]=(d[p*2]*b2[p]%mod+(m-s+1)*b1[p]%mod)%mod;
	d[p*2+1]=(d[p*2+1]*b2[p]+(t-m)*b1[p])%mod;
	b2[p*2]=(b2[p*2]*b2[p])%mod,b2[p*2+1]=(b2[p*2+1]*b2[p])%mod;
	b1[p*2]=(b1[p*2]*b2[p]+b1[p])%mod,b1[p*2+1]=(b1[p*2+1]*b2[p]+b1[p])%mod;
	b2[p]=1;
	b1[p]=0;
}
void build(int s,int t,int p)
{
	if(s==t)
	{
		d[p]=arr[s];
		return;
	}
	int m = s+((t-s)>>1);
	build(s,m,p*2);
	build(m+1,t,p*2+1);
	d[p]=(d[p*2]+d[p*2+1])%mod;
}
void update_add(int l,int r,int c,int s,int t,int p)
{
	if(r<s||l>t)return;
	if(s>=l&&t<=r)
	{
		d[p]=(d[p]+(t-s+1)*c%mod)%mod,b1[p]=(b1[p]+c)%mod;
		return;
	}
	int m = s+((t-s)>>1);
	if(b1[p]||b2[p]!=1)push(m,s,t,p);
	update_add(l,r,c,s,m,p*2);
	update_add(l,r,c,m+1,t,p*2+1);
	d[p]=(d[p*2]+d[p*2+1])%mod;
}
void update_mul(int l,int r,int c,int s,int t,int p)
{
	if(r<s||l>t)return;
	if(s>=l&&r>=t)
	{
		d[p]=(d[p]*c)%mod;
		b2[p]=(b2[p]*c)%mod;
		b1[p]=(b1[p]*c)%mod;
		return;
	}
	int m = s+((t-s)>>1);
	if(b1[p]||b2[p]!=1)push(m,s,t,p);
	update_add(l,r,c,s,m,p*2);
	update_add(l,r,c,m+1,t,p*2+1);
	d[p]=(d[p*2]+d[p*2+1])%mod;
}
int query(int l,int r,int s,int t,int p)
{
	if(r<s||l>t)return 0;
	if(s>=l&&t<=r)return d[p]%mod;
	int m = s+((t-s)>>1);
	if(b1[p]||b2[p]!=1)push(m,s,t,p);
	return (query(l,r,s,m,p*2)+query(l,r,m+1,t,p*2+1))%mod;
}
void solve()
{
	cin>>n>>q>>mod;
	for(int i=1;i<=n;i++)cin>>arr[i];
	for(int i=1;i<=N;i++)b2[i]=1;//初始化乘法标记
	build(1,n,1);
	while(q--)
	{
		int op;
		int x,y,k;
		cin>>op;
		if(op==1)
		{
			cin>>x>>y>>k;//乘法
			update_mul(x,y,k,1,n,1);
		}
		else if(op==2)
		{
			cin>>x>>y>>k;//加法
			update_add(x,y,k,1,n,1);
		}
		else
		{
			cin>>x>>y;//求和
			cout<<query(x,y,1,n,1)<<endl;
		}
	}
}

signed main()
{
	std::ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	times=1;
	//cin >> times;
	while (times--)
	{
		solve();
	}
	return 0;
}



2023/12/31 17:37
加载中...