社区讨论
除了样例啥也没过求调
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 条回复,欢迎继续交流。
正在加载回复...