社区讨论

不理解自己为什么过了

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

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mm2u4g3j
此快照首次捕获于
2026/02/26 10:19
2 周前
此快照最后确认于
2026/02/26 10:19
2 周前
查看原帖
70pts代码:
CPP
#include<bits/stdc++.h>
using namespace std;
long long n,q,m,a[100005],tr[400005],tag1[400005],tag2[400005];
void pushdown(long long rt,long long l,long long r){
	if(tag1[rt]||tag2[rt]>1){
		tag1[rt*2]=(tag1[rt*2]*tag2[rt]+tag1[rt])%m;
		tag2[rt*2]=(tag2[rt*2]*tag2[rt])%m;
		tr[rt*2]=(tr[rt*2]*tag2[rt]+tag1[rt]*((l+r)/2-l+1))%m;
		tag1[rt*2+1]=(tag1[rt*2+1]*tag2[rt]+tag1[rt])%m;
		tag2[rt*2+1]=(tag2[rt*2+1]*tag2[rt])%m;
		tr[rt*2+1]=(tr[rt*2+1]*tag2[rt]+tag1[rt]*(r-(l+r)/2))%m;
		tag1[rt]=0;
		tag2[rt]=1;
	}
}
void build(long long rt,long long l,long long r){
	tag2[rt]=1;
	if(l==r){
		tr[rt]=a[l]%m;
		return ;
	}
	build(rt*2,l,(l+r)/2);
	build(rt*2+1,(l+r)/2+1,r);
	tr[rt]=(tr[rt*2]+tr[rt*2+1])%m;
}
void add(long long rt,long long l,long long r,long long x,long long y,long long k){
	if(x<=l&&r<=y){
		tag1[rt]=(tag1[rt]+k)%m;
		tr[rt]=(tr[rt]+k*(r-l+1))%m;
		return;
	}
	pushdown(rt,l,r);
	if(x<=(l+r)/2)
		add(rt*2,l,(l+r)/2,x,y,k);
	if(y>(l+r)/2)
		add(rt*2+1,(l+r)/2+1,r,x,y,k);
	tr[rt]=(tr[rt*2]+tr[rt*2+1])%m;
}
void ch(long long rt,long long l,long long r,long long x,long long y,long long k){
	if(x<=l&&r<=y){
		tag1[rt]=(tag1[rt]*k)%m;
		tag2[rt]=(tag2[rt]*k)%m;
		tr[rt]=(tr[rt]*k)%m;
		return;
	}
	pushdown(rt,l,r);
	if(x<=(l+r)/2)
		ch(rt*2,l,(l+r)/2,x,y,k);
	if(y>(l+r)/2)
		ch(rt*2+1,(l+r)/2+1,r,x,y,k);
	tr[rt]=(tr[rt*2]+tr[rt*2+1])%m;
}
long long sum(long long rt,long long l,long long r,long long x,long long y){
	if(x<=l&&r<=y){
		return tr[rt];
	}
	pushdown(rt,l,r);
	long long ans=0;
	if(x<=(l+r)/2){
		ans=(ans+sum(rt*2,l,(l+r)/2,x,y))%m;	
	}
	if(y>(l+r)/2){
		ans=(ans+sum(rt*2+1,(l+r)/2+1,r,x,y))%m;
	}
	return ans;
}
int main(){
	scanf("%lld%lld%lld",&n,&q,&m);
	for(long long i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	while(q--){
		long long op,x,y,k;
		scanf("%lld",&op);
		if(op==2){
			scanf("%lld%lld%lld",&x,&y,&k);
			add(1,1,n,x,y,k);
		}else if(op==1){
			scanf("%lld%lld%lld",&x,&y,&k);
			ch(1,1,n,x,y,k);
		}else{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",sum(1,1,n,x,y));
		}
	}
	return 0;
} 
100分就把第六行的tag2[rt]>1改成了!=1,不理解。。。

回复

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

正在加载回复...