社区讨论

除了样例啥也没过求调

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@mdn7k9ev
此快照首次捕获于
2025/07/28 22:33
7 个月前
此快照最后确认于
2025/11/04 03:34
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
#define N 100005
#define L tr[no].l
#define R tr[no].r
#define lc tr[no].sl
#define rc tr[no].sr
#define num tr[no].numb
#define mu tr[no].mul
#define ad tr[no].add
using namespace std;
int mod,a[N],bh;
struct pnt{
	int l,r,sl,sr,numb,mul,add;
}tr[N<<2];
void sp(int),build(int&,int,int),mul(int,int,int,int),add(int,int,int,int);
int sum(int,int,int);
signed main(){
	int n,m;
	scanf("%lld%lld%lld",&n,&m,&mod);
	for(int i=1;i<=n;++i)
		scanf("%lld",&a[i]),a[i]%=mod;
	int k=0;
	build(k,1,n);
	for(int i=1;i<=m;++i){
		int z;
		scanf("%lld",&z);
		if(z<2){
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			mul(1,x,y,k);
//			cout<<"\n";
//			for(int j=1;j<=n;++j)
//				printf("%lld ",sum(1,j,j));
//			cout<<"\n\n";
		}
		else if(z&1){
			int x,y;
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",sum(1,x,y));
		}
		else{
			int x,y,k;
			scanf("%lld%lld%lld",&x,&y,&k);
			add(1,x,y,k);
//			cout<<"\n";
//			for(int j=1;j<=n;++j)
//				printf("%lld ",sum(1,j,j));
//			cout<<"\n\n";
		}
	}
	return 0;
}
void build(int &no,int l,int r){
	no=++bh;
	L=l,R=r; mu=1;
	if(l==r){
		num=a[l];
		return;
	}
	int mi=l+r>>1;
	build(lc,l,mi);
	build(rc,mi+1,r); 
	num=tr[lc].numb+tr[rc].numb,num%=mod;
	return ;
}
void sp(int no){
	int mi=L+R>>1;
	if(lc){
		tr[lc].add*=mu,tr[lc].add%=mod;
		tr[lc].mul*=mu,tr[lc].mul%=mod;
		tr[lc].numb*=mu,tr[lc].add%=mod;
		tr[lc].numb+=ad*(mi-L+1)%mod,tr[lc].numb%=mod;
		tr[lc].add+=ad,tr[lc].add%=mod;
	}
	if(rc){
		tr[rc].add*=mu,tr[rc].add%=mod;
		tr[rc].mul*=mu,tr[rc].mul%=mod;
		tr[rc].numb*=mu,tr[rc].add%=mod;
		tr[rc].numb+=ad*(R-mi)%mod,tr[rc].numb%=mod;
		tr[rc].add+=ad,tr[rc].add%=mod;
	}
	mu=1,ad=0;
}
void mul(int no,int x,int y,int k){
	if(x>R||y<L||!no)
		return ;
	if(L>=x&&R<=y){
		num*=k,num%=mod;
		ad*=k,ad%=mod;
		return ;
	}
	sp(no);
	mul(lc,x,y,k);
	mul(rc,x,y,k);
	num=tr[lc].numb+tr[rc].numb,num%=mod;
	return ;
}
void add(int no,int x,int y,int k){
	if(R<x||L>y||!no)
		return ;
	if(L>=x&&R<=y){
		num+=k*(R-L+1)%mod,num%=mod;
		ad+=k,ad%=mod;
		return ;
	}
	sp(no);
	add(lc,x,y,k);
	add(rc,x,y,k);
	num=tr[lc].numb+tr[rc].numb,num%=mod;
	return ;
}
int sum(int no,int x,int y){
	if(R<x||L>y||!no)
		return 0;
	if(L>=x&&R<=y)
		return num;
	sp(no);
	int ans=sum(lc,x,y);
	ans+=sum(rc,x,y);
	return ans%mod;	
}
//5929 366982 16361 18322 406950 496129 491235 486999
/*
5 8 1000
1 2 4 3 5
1 3 3 7
2 4 5 4
2 4 5 7
1 3 5 6
1 1 2 7
1 2 4 2
2 3 5 2
1 1 5 3
*/

回复

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

正在加载回复...