社区讨论
萌新刚学线段树,悬赏一关
P3373【模板】线段树 2参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo14ex4t
- 此快照首次捕获于
- 2023/10/22 15:01 2 年前
- 此快照最后确认于
- 2023/11/02 14:33 2 年前
CPP
#include<bits/stdc++.h>
#define int long long
#define double long double
#define INF INT_MAX
using namespace std;
const int maxn=1e5+5;
int n,m,mod;
int a[maxn];
struct Tree{
int l,r,val,add;
#define l(x) t[x].l
#define r(x) t[x].r
#define sum(x) t[x].val
#define add(x) t[x].add
}t[maxn*4];
void build(int dq,int l,int r){
l(dq)=l,r(dq)=r;
if(l==r){
sum(dq)=a[l]%mod;
return;
}
int mid=(l+r)/2;
build(dq*2,l,mid);
build(dq*2+1,mid+1,r);
sum(dq)=sum(dq*2)+sum(dq*2+1);
}
void spread1(int dq){
if(add(dq)){
sum(dq*2)+=add(dq)*(r(dq*2)-l(dq*2)+1);
sum(dq*2+1)+=add(dq)*(r(dq*2+1)-l(dq*2+1)+1);
add(dq*2)+=add(dq);
add(dq*2+1)+=add(dq);
add(dq)=0;
}
}
void change1(int dq,int l,int r,int d){
if(l<=l(dq) && r(dq)<=r){
sum(dq)+=(d*(r(dq)-l(dq)+1))%mod;
add(dq)+=d;
return;
}
spread1(dq);
int mid=(l(dq)+r(dq))/2;
if(l<=mid) change1(dq*2,l,r,d);
if(r>mid) change1(dq*2+1,l,r,d);
sum(dq)=(sum(dq*2)+sum(dq*2+1))%mod;
}
//----------------------------------------------------------------
void spread2(int dq){
if(add(dq)){
sum(dq*2)*=(add(dq)*(r(dq*2)-l(dq*2)+1))%mod;
sum(dq*2+1)*=(add(dq)*(r(dq*2+1)-l(dq*2+1)+1))%mod;
add(dq*2)*=add(dq)%mod;
add(dq*2+1)*=add(dq)%mod;
add(dq)=0;
}
}
void change2(int dq,int l,int r,int d){
if(l<=l(dq) && r(dq)<=r){
sum(dq)*=(d*(r(dq)-l(dq)+1))%mod;
add(dq)*=d;
return;
}
spread2(dq);
int mid=(l(dq)+r(dq))/2;
if(l<=mid) change2(dq*2,l,r,d);
if(r>mid) change2(dq*2+1,l,r,d);
sum(dq)=(sum(dq*2)+sum(dq*2+1))%mod;
}
//----------------------------------------------------------------
int ask(int dq,int l,int r){
if(l<=l(dq) && r(dq)<=r) return sum(dq)%mod;
spread1(dq);
spread2(dq);
int mid=(l(dq)+r(dq))/2;
int k=0;
if(l<=mid) k+=ask(dq*2,l,r);
if(r>mid) k+=ask(dq*2+1,l,r);
return k%mod;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
int op,x,y,k;
cin>>op>>x>>y;
if(op==1){
cin>>k;
change1(1,x,y,k);
}
else if(op==2){
cin>>k;
change2(1,x,y,k);
}
else cout<<ask(1,x,y)%mod<<endl;
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...