社区讨论

求求,大佬求调

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lob5yjsw
此快照首次捕获于
2023/10/29 15:42
2 年前
此快照最后确认于
2023/11/03 22:00
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=100005;
int n,m,mod;
int a[maxn],ans[maxn<<2],mu[maxn<<2],add[maxn<<2];
inline int ls(int x)
{
	return x<<1;
}
inline int rs(int x)
{
	return x<<1|1;
}
void pushup(int p){
	ans[p]=ans[ls(p)]+ans[rs(p)];
}
void build(int p,int l,int r)
{
	if(l==r)
	{
		ans[p]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p);
}
void pushdown(int p,int l,int r){
	int mid=(l+r)>>1;
	
	ans[ls(p)]=((ans[ls(p)]*mu[p])+add[p]*(mid-l+1))%mod;
	mu[ls(p)]=(mu[ls(p)]*mu[p])%mod;
	add[ls(p)]=(add[ls(p)]*mu[p]+add[ls(p)]+add[p])%mod;
	
	ans[rs(p)]=((ans[rs(p)]*mu[p])+add[p]*(r-mid))%mod;
	mu[rs(p)]=(mu[rs(p)]*mu[p])%mod;
	add[rs(p)]=(add[rs(p)]*mu[p]+add[rs(p)]+add[p])%mod;
	
	add[p]=0;
	mu[p]=1;
}
void update_mu(int p,int l,int r,int nl,int nr,int k){
	if(nl<=l&&nr>=r)
	{
		ans[p]=(ans[p]*k)%mod;
		mu[p]=(mu[p]*k)%mod;
		add[p]=(add[p]*k)%mod;
		return ;
	}
	pushdown(p,l,r);
	int mid=(l+r)>>1;
	if(nl<=mid)update_mu(ls(p),l,mid,nl,nr,k);
	if(mid<nr)update_mu(rs(p),mid+1,r,nl,nr,k);
	pushup(p);
}
void update_add(int p,int l,int r,int nl,int nr,int k){
	if(nl<=l&&nr>=r)
	{
		ans[p]=(ans[p]+(r-l+1)*k)%mod;
		add[p]=add[p]+k;
		return ;
	}
	pushdown(p,l,r);
	int mid=(l+r)>>1;
	if(nl<=mid)update_add(ls(p),l,mid,nl,nr,k);
	if(mid<nr)update_add(rs(p),mid+1,r,nl,nr,k);
	pushup(p);
}
int query(int qx,int qy,int l,int r,int p)
{
	int res=0;
	if(qx<=l&&qy>=r)return (ans[p]%mod);
	int mid=(l+r)>>1;
	pushdown(p,l,r);
	if(qx<=mid)res+=query(qx,qy,l,mid,ls(p))%mod;
	if(qy>mid) res+=query(qx,qy,mid+1,r,rs(p))%mod;
	return res;
}
signed main(){
	scanf("%lld%lld%lld",&n,&m,&mod);
	for(int i=1;i<=n;i++)
		cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int opt;
		cin>>opt;
		if(opt==1)
		{
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			update_mu(1,1,n,x,y,k);
		}
		if(opt==2)
		{
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			update_add(1,1,n,x,y,k);
		}
		if(opt==3)
		{
			int x,y;
			cin>>x>>y;
			printf("%lld\n",query(x,y,1,n,1));
		}
	}
	return 0;
}

回复

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

正在加载回复...