社区讨论
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 条回复,欢迎继续交流。
正在加载回复...