社区讨论

过样例0pts求hack,玄关

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@mk458ma2
此快照首次捕获于
2026/01/07 22:58
上个月
此快照最后确认于
2026/01/10 19:30
上个月
查看原帖
要小一点的好操作的,自己没构出来,测试点1太大没法调qwq
CPP
#include<bits/stdc++.h>
using namespace std;
int n,Q,mod;
long long a[100005];
long long s[400005],add[400005],times[400005];
void build(int l,int r,int rt){
	times[rt]=1; 
	if (l==r){
		s[rt]=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(mid+1,r,rt*2+1);
	build(l,mid,rt*2);
	s[rt]=s[rt*2]+s[rt*2+1];
}
void pushdown(int l,int r,int rt){
	if (l==r)
		return;
	int mid=(l+r)/2;
	(times[rt*2]*=times[rt])%=mod;
	(times[rt*2+1]*=times[rt])%=mod;
	add[rt*2]=(add[rt*2]*times[rt]+add[rt])%mod;
	add[rt*2+1]=(add[rt*2+1]*times[rt]+add[rt])%mod;
	s[rt*2]=(s[rt*2]*times[rt]+add[rt]*(mid-l+1))%mod;
	s[rt*2+1]=(s[rt*2+1]*times[rt]+add[rt]*(r-mid))%mod;
	add[rt]=0; 
	times[rt]=1;
}
void update1(int x,int y,long long k,int l,int r,int rt){
	if (l>=x&&r<=y){
		(times[rt]*=k)%=mod;
		(s[rt]*=k)%=mod;
		return;
	}
	pushdown(l,r,rt);
	int mid=(l+r)/2;
	if (x<=mid){
		update1(x,y,k,l,mid,rt*2); 
	}
	if (y>=mid+1){
		update1(x,y,k,mid+1,r,rt*2+1);
	}
	s[rt]=s[rt*2]+s[rt*2+1];
}
void update2(int x,int y,long long k,int l,int r,int rt){
	if (l>=x&&r<=y){
		add[rt]+=k;
		s[rt]+=(r-l+1)*k;
		return;
	}
	pushdown(l,r,rt);
	int mid=(l+r)/2;
	if (x<=mid){
		update2(x,y,k,l,mid,rt*2); 
	}
	if (y>=mid+1){
		update2(x,y,k,mid+1,r,rt*2+1);
	}
	s[rt]=s[rt*2]+s[rt*2+1];
}
long long sum(int x,int y,int l,int r,int rt){
	if (l>=x&&r<=y){
		return s[rt]%mod;
	}
	pushdown(l,r,rt);
	int mid=(l+r)/2;
	long long ans=0;
	if (x<=mid){
		ans+=sum(x,y,l,mid,rt*2); 
	}
	if (y>=mid+1){
		ans+=sum(x,y,mid+1,r,rt*2+1);
	}
	return ans%mod;
}
int main(){
	cin>>n>>Q>>mod;
	for (int i=1;i<=n;i++)
		cin>>a[i];
	build(1,n,1);
	while (Q--){
		int op;
		cin>>op;
		if (op==1){
			int x,y;
			long long k;
			cin>>x>>y>>k;
			update1(x,y,k,1,n,1);
		}
		else if (op==2){
			int x,y;
			long long k;
			cin>>x>>y>>k;
			update2(x,y,k,1,n,1);
		}
		else{
			int x,y;
			cin>>x>>y;
			cout<<sum(x,y,1,n,1)<<'\n';
		}
	}
	return 0;
} 

回复

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

正在加载回复...