社区讨论

0分求条

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

讨论操作

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

当前回复
8 条
当前快照
1 份
快照标识符
@m5uslnty
此快照首次捕获于
2025/01/13 16:39
去年
此快照最后确认于
2025/11/04 11:40
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100010;
int n,m,M,a[4*N],op;
int tree[4*N],tag1[4*N],tag2[4*N];//树和懒标记 
int ls(int p);
int rs(int p);
int query(int L,int R,int p,int l,int r);
void build(int p,int l,int r);
void addtag(int p,int l,int r,int d);
void updata(int L,int R,int p,int l,int r,int d,int o);
void push_up(int p);
void push_down(int p,int l,int r);
signed main(){
	freopen(".out","w",stdout);
	cin>>n>>m>>M;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=4*N;i++) tag2[i]=1;
	while(m--){
		cin>>op;
		if(op==1){
			int L,R,d;
			cin>>L>>R>>d;
			updata(L,R,1,1,n,d,1);
		}
		else if(op==2){
			int L,R,d;
			cin>>L>>R>>d;
			updata(L,R,1,1,n,d,2);
		}
		else{
			int L,R;
			cin>>L>>R;
			cout<<query(L,R,1,1,n)%M<<"\n";
		}
	}
	return 0;
}
int ls(int p){
	return p<<1;
}
int rs(int p){
	return p<<1|1;
}
void addtag1(int p,int l,int r,int d){
	tag1[p]+=d%M;
	tree[p]+=d*(r-l+1)%M;
}
void addtag2(int p,int l,int r,int d){
	tag1[p]*=d%M;
	tag2[p]*=d%M;
	tree[p]*=d%M;
}
void push_up(int p){//赋值 
	tree[p]=(tree[ls(p)]+tree[rs(p)])%M;
}
void push_down(int p,int l,int r){//传递tag 
	if(tag1[p]){
		int mid=(l+r)>>1;
		addtag1(ls(p),l,mid,tag1[p]);
		addtag1(rs(p),mid+1,r,tag1[p]);
		tag1[p]=0;
	}
	if(tag2[p]>1){
		int mid=(l+r)>>1;
		addtag2(ls(p),l,mid,tag2[p]);
		addtag2(rs(p),mid+1,r,tag2[p]);
		tag2[p]=1;
	}
}
void build(int p,int l,int r){//建树 
	if(l==r){
		tree[p]=a[l]%M;
		return;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	push_up(p);
}
int query(int L,int R,int p,int l,int r){//区间查询 
	if(L<=l&&r<=R) return tree[p]%M;
	push_down(p,l,r);
	int mid=(l+r)>>1,s=0;
	if(L<=mid) s+=query(L,R,ls(p),l,mid);
	if(R>mid) s+=query(L,R,rs(p),mid+1,r);
	return s;
	//query(L,R,1,1,n);
}
void updata(int L,int R,int p,int l,int r,int d,int o){//区间修改 
	if(L<=l&&r<=R){
		if(o==2) addtag1(p,l,r,d);
		else addtag2(p,l,r,d);
		return;
	}
	push_down(p,l,r);
	int mid=(l+r)>>1;
	if(L<=mid) updata(L,R,ls(p),l,mid,d,o);
	if(R>mid) updata(L,R,rs(p),mid+1,r,d,o);
	push_up(p);
}

回复

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

正在加载回复...