其他分享
首页 > 其他分享> > P3373&&ybtoj【数据结构】4章4题【【模板】线段树2】

P3373&&ybtoj【数据结构】4章4题【【模板】线段树2】

作者:互联网

【模板】线段树2

题目

P3373


解析

前置知识:线段树区间加区间求和
好的,现在我们考虑设计懒标记:一个乘,一个加,当然是先乘再加才不会对加产生影响
加法直接按区间加下传,乘法就需要两个懒标记一起乘
注意:乘法的懒标记初始为1
还有就是下传时要先下传乘法,再下传加法
剩下的就是板子了
哦对了,本题要开

long long

code:

#include<cstdio>
#define int long long
using namespace std;
inline bool idigit(char x){return (x<'0'|x>'9')?0:1;}
inline int read()
{
	int num=0,f=1;
	char c=0;
	while(!idigit(c=getchar())){if(c=='-')f=-1;}
	while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
	return num*f;
}
inline void write(int x)
{
	int F[20];
	int tmp=x>0?x:-x;
	if(x<0)putchar('-');
	int cnt=0;
	while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}
	while(cnt>0)putchar(F[--cnt]);
	if(x==0)putchar('0');
	putchar('\n');
}
int n,m,p,op,x,y,z,a[100010],sum[400010],add[400010],mul[400010];
inline void build(int l,int r,int k)
{
	mul[k]=1;
	if(l==r){sum[k]=a[l]%p;return;}
	int mid=(l+r)>>1;
	build(l,mid,k<<1);
	build(mid+1,r,k<<1|1);
	sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
}
inline void update(int l,int r,int k,int s){add[k]=(add[k]+s)%p,sum[k]=(sum[k]+(r-l+1)*s)%p;}
inline void update_mul(int l,int r,int k,int s){mul[k]=mul[k]*s%p,add[k]=add[k]*s%p,sum[k]=sum[k]*s%p;}
inline void pushdown(int l,int r,int k){if(add[k]||mul[k]!=1){int mid=(l+r)>>1;update_mul(l,mid,k<<1,mul[k]),update_mul(mid+1,r,k<<1|1,mul[k]),mul[k]=1,update(l,mid,k<<1,add[k]),update(mid+1,r,k<<1|1,add[k]),add[k]=0;}}
inline void Add(int l,int r,int L,int R,int k,int q)
{
	if(L<=l&&r<=R){update(l,r,k,q);return;}
	pushdown(l,r,k);
	int mid=l+r>>1;
	if(L<=mid)Add(l,mid,L,R,k<<1,q);
	if(R>mid)Add(mid+1,r,L,R,k<<1|1,q);
	sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
}
inline void Mul(int l,int r,int L,int R,int k,int q)
{
	if(L<=l&&r<=R){update_mul(l,r,k,q);return;}
	pushdown(l,r,k);
	int mid=l+r>>1;
	if(L<=mid)Mul(l,mid,L,R,k<<1,q);
	if(R>mid)Mul(mid+1,r,L,R,k<<1|1,q);
	sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
}
inline int query(int l,int r,int L,int R,int k)
{
	if(L<=l&&r<=R)return sum[k];
	pushdown(l,r,k);
	int mid=l+r>>1,ans=0;
	if(L<=mid)ans+=query(l,mid,L,R,k<<1);
	if(R>mid)ans+=query(mid+1,r,L,R,k<<1|1);
	return ans%p;
}
signed main()
{
	n=read(),m=read(),p=read();
	for(int i=1;i<=n;++i)a[i]=read();
	build(1,n,1);
	while(m--)
	{
		op=read();
		if(op==1)x=read(),y=read(),z=read(),Mul(1,n,x,y,1,z);
		else if(op==2)x=read(),y=read(),z=read(),Add(1,n,x,y,1,z);
		else x=read(),y=read(),write(query(1,n,x,y,1));
	}
	return 0;
}

标签:int,ybtoj,sum,mid,read,add,&&,mul,P3373
来源: https://blog.csdn.net/zhanglili1597895/article/details/117825249