社区讨论

求助,SOS!!!

P3373【模板】线段树 2参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lotqkauw
此快照首次捕获于
2023/11/11 15:39
2 年前
此快照最后确认于
2023/11/11 17:16
2 年前
查看原帖
求助
CPP
#include <bits/stdc++.h>
using namespace std;
#define open ios_base::sync_with_stdio(0) , cin.tie(0) 
#define ll long long
#define pb push_back
#define lc p<<1
#define rc p<<1|1
const int N = 1e5+10;
ll sum[N<<2],add[N<<2],mul[N<<2];
int a[N];
int n,q,m;

void pushup(int p)
{
	sum[p] = (sum[lc] + sum[rc]) % m;
}

void pushdown(int l,int r,int p)
{
	int ad = add[p] , mu = mul[p] , mid =(l+r)/2 ;
	
	mul[lc] = (mul[lc]*mu) % m , mul[rc] = (mul[rc]*mu) % m ;
	add[lc] = (add[lc]*mu + ad) % m , add[rc] = (add[rc]*mu + ad) % m ;
	//l mid    mid+1  r
	sum[lc] = (sum[lc]*mu + (mid-l+1)*ad) % m ;
	sum[rc] = (sum[rc]*mu + (r-mid)*ad) % m ;
	add[p] = 0 , mul[p] = 1;
}

void build(int l,int r,int p)
{
	if(l==r)
	{
		add[p] = 0 , mul[p] = 1 , sum[p] = a[l] % m ;
		return ;
	}
	int mid = (l+r)/2;
	
	build(l,mid,lc) , build(mid+1,r,rc) , pushup(p);
	
}


//乘法
void change1(int l,int r,int p,int ql,int qr,int k)
{
	if(ql<=l && r<=qr)
	{
		mul[p] = (mul[p]*k) % m , add[p] = (add[p]*k) % m ,sum[p] = (sum[p]*k) % m;	
		return ;
	}
	pushdown(l,r,p);
	
	int mid = (l+r)/2;
	if(ql<=mid)		change1(l,mid,lc,ql,qr,k);
	if(mid+1<=qr)	change1(mid+1,r,rc,ql,qr,k);
	pushup(p);
}

//加法
void change2(int l,int r,int p,int ql,int qr,int k)
{
	if(ql<=l && r<=qr)
	{
		add[p] = (add[p] + k) % m , sum[p] = (sum[p] + (r-l+1)*k ) % m ;	
		return ;
	}
	pushdown(l,r,p);
	
	int mid = (l+r)/2;
	if(ql<=mid)		change2(l,mid,lc,ql,qr,k);
	if(mid+1<=qr)	change2(mid+1,r,rc,ql,qr,k);
	pushup(p);
}

ll ask(int l,int r,int p,int ql,int qr)
{
	if(ql<=l && r<=qr)
	{
		return sum[p];
	}
	pushdown(l,r,p);
	int mid = (l+r)/2;
	ll s = 0;
	if(ql<=mid)		s += ask(l,mid,lc,ql,qr);
	if(mid+1<=qr)	s += ask(mid+1,r,rc,ql,qr);
	pushup(p);
	return s%m;
}


int main()
{
	cin>>n>>q>>m;
	
	for(int i=1; i<=n; i++)		cin>>a[i];
	
	build(1,n,1);
	
	int op,x,y,k;
	for(int i=1; i<=q; i++)
	{
		cin>>op>>x>>y;
		if(op==1)
			cin>>k , change1(1,n,1,x,y,k);
		else if(op==2)
			cin>>k , change2(1,n,1,x,y,k);
		else
			cout<<ask(1,n,1,x,y)<<"\n";
	}
	
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...