样例未过,第二个输出32,求调,悬关(码风正常)
查看原帖
样例未过,第二个输出32,求调,悬关(码风正常)
546681
lcbridgeAK CSP-S楼主2023/5/6 22:40
#include <bits/stdc++.h>
#define int long long
#define MAXN 100005
using namespace std;
struct SegmentTree{
	int l,r,sum,add,mul,len;	 
}t[MAXN*4];
int a[MAXN],n,m,p;
void pushup(int x){
	t[x].sum=(t[x*2].sum+t[x*2+1].sum)%p;
}
void build(int x,int l,int r){
	t[x].l=l;
	t[x].r=r;
	t[x].len=r-l+1;
	t[x].mul=1;
	//cout<<"x="<<x<<" l="<<l<<" r="<<r<<endl;
	if(l==r){
		t[x].sum=a[l]%p;
		return ;
	}
	int mid=(l+r)>>1;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	pushup(x);
}
void pushdown(int x){
	t[x*2].sum=(t[x].mul*t[x*2].sum+(t[x*2].len*t[x].add)%p)%p;
	t[x*2+1].sum=(t[x].mul*t[x*2+1].sum+(t[x*2+1].len*t[x].add)%p)%p;
	
	t[x*2].mul=(t[x*2].mul*t[x].mul)%p;
	t[x*2+1].mul=(t[x*2+1].mul*t[x].mul)%p;
	
	t[x*2].add=(t[x*2].add*t[x].mul+t[x].add)%p;
	t[x*2+1].add=(t[x*2+1].add*t[x].mul+t[x].add)%p;
	
	//cout<<t[x*2].add<<' '<<t[x*2].mul<<"\n"<<t[x*2+1].add<<' '<<t[x*2+1].mul<<"\n";
	t[x].add=0;
	t[x].mul=1;
}
int query(int x,int l,int r){
	//cout<<"x="<<x<<" l="<<l<<" r="<<r<<endl;
	int L=t[x].l,R=t[x].r;
	if(l<=L&&r>=R)return t[x].sum;
	int mid=(L+R)>>1,val=0;
	pushdown(x);
	if(l<=mid)val=(val+query(x*2,l,r))%p;
	if(r>mid)val=(val+query(x*2+1,l,r))%p;
	return val;
} 
void changeadd(int x,int l,int r,int k){
	int L=t[x].l,R=t[x].r;
	if(l<=L&&R<=r){
		t[x].sum=(t[x].sum+k*t[x].len)%p;
		t[x].add=(k+t[x].add)%p;
		return ;
	}
	pushdown(x);
	int mid=(L+R)>>1;
	if(l<=mid)changeadd(x*2,l,r,k);
	if(r>mid)changeadd(x*2+1,l,r,k);
	pushup(x);
	//cout<<"x="<<x<<" sum="<<t[x].sum<<"\n";
}
void changemul(int x,int l,int r,int k){
	int L=t[x].l,R=t[x].r;
	if(l<=L&&R<=r){
		t[x].add=(t[x].add*k)%p;
		t[x].mul=(t[x].mul*k)%p;
		t[x].sum=(t[x].sum*k)%p;
		return ;
	}
	pushdown(x);
	int mid=(L+R)>>1;
	if(l<=mid)changeadd(x*2,l,r,k);
	if(r>mid)changeadd(x*2+1,l,r,k);
	pushup(x);
	//cout<<"x="<<x<<" sum="<<t[x].sum<<"\n";
}
signed main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	build(1,1,n);
	while(m--){
		int opr; 
		scanf("%lld",&opr);
		if(opr==1){
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			changemul(1,x,y,k);
		}
		if(opr==2){
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			changeadd(1,x,y,k);
		}
		if(opr==3){
			int x,y;
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(1,x,y));
		}
	}
	return 0;
} 

谢谢!

2023/5/6 22:40
加载中...