求助,线段树过了样例,看着能%p的地方都%了,但全WA
查看原帖
求助,线段树过了样例,看着能%p的地方都%了,但全WA
568243
Windows_Update楼主2022/2/9 09:23

如题
看着能%p的地方都%了,但全WA
下载下来后测试点1的正解输出如下:

478836
562114

我的程序:

329471
403927

我不知道该怎么办好了,求大佬调教qwq
源代码:

#include<bits/stdc++.h>
using namespace std;
long long arr[1000000],n,m,x,y,k,op,p;
struct node{
	long long l,r,sum,len,tag1,tag2;
	node operator+(const node &x){
		return {l,x.r,(sum+x.sum)%p,len+x.len,0,0};
	} 
}stree[4000000];
#define pushup(now) stree[now]=stree[now<<1]+stree[now<<1|1]
inline void givetag1(int now,long long tag){//这里是维护乘法的懒标记 
	if(stree[now].l==stree[now].r){
		stree[now].sum=stree[now].sum%p*tag%p;
		return;
	}
	stree[now].tag1=stree[now].tag1%p*tag%p;
	stree[now].sum=stree[now].sum%p*stree[now].len*tag%p;
}
inline void givetag2(int now,long long tag){//这里是维护加法的 
	if(stree[now].l==stree[now].r){
		stree[now].sum=stree[now].sum%p+tag%p;
		return;
	} 
	stree[now].tag2=stree[now].tag2%p+tag%p;
	stree[now].sum=stree[now].sum%p+stree[now].len*tag%p;
}
inline void pushtag1(int now){
	givetag1(now<<1,stree[now].tag1);
	givetag1(now<<1|1,stree[now].tag1);
	stree[now].tag1=0;
}
inline void pushtag2(int now){
	if(stree[now].tag1)pushtag1(now);
	givetag2(now<<1,stree[now].tag2);
	givetag2(now<<1|1,stree[now].tag2);
	stree[now].tag2=0;
}
void build(int l,int r,int now){
	if(l==r){
		stree[now]={l,l,arr[l]%p,1,0,0};
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,now<<1);
	build(mid+1,r,now<<1|1);
	pushup(now);
}
void change(int l,int r,int k,int v,int now){
	if(stree[now].tag1||stree[now].tag2)pushtag2(now);
	if(stree[now].l>=l&&stree[now].r<=r){
		if(v==0){
			givetag1(now,k);
		}else{
			givetag2(now,k);
		}
		return;
	}
	if(stree[now].l>r||stree[now].r<l){
		return;
	}else{
		change(l,r,k,v,now<<1);
		change(l,r,k,v,now<<1|1);
	}
	pushup(now);
}
long long query(int l,int r,int now){
	if(stree[now].tag1||stree[now].tag2)pushtag2(now);
	if(stree[now].l>=l&&stree[now].r<=r)return stree[now].sum%p;
	if(stree[now].l>r||stree[now].r<l)return 0%p;
	return (query(l,r,now<<1)%p+query(l,r,now<<1|1)%p)%p;
} 
inline long long read(){
	int x=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*w;
}
int main(){
	n=read(),m=read(),p=read();
	for(int i=1;i<=n;++i){
		arr[i]=read()%p;
	}
	build(1,n,1);
	while(m--){
		op=read();
		if(op==1){
			x=read(),y=read(),k=read();
			change(x,y,k,0,1);
		}else if(op==2){
			x=read(),y=read(),k=read();
			change(x,y,k,1,1);
		}else{
			x=read(),y=read();
			printf("%lld\n",query(x,y,1)%p);
		}
	}
	return 0;
} 
2022/2/9 09:23
加载中...