记录编号 |
598454 |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
题目名称 |
[SYOI 2018] 简单的线段树 |
最终得分 |
100 |
用户昵称 |
梦那边的美好ET |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
14.177 s |
提交时间 |
2025-01-24 15:48:41 |
内存使用 |
5.91 MiB |
显示代码纯文本
#include<bits/stdc++.h>
#define maxn 100010
#define ll long long
using namespace std;
int n,m,a1,a2,a3,s,a[maxn];
ll sum[maxn*4],lz1[maxn*4],lz2[maxn*4],mod;
void build(int p,int l,int r){
lz1[p]=1;
if(l==r)return;
int mid=(l+r)/2;
build(p*2,l,mid);build(p*2+1,mid+1,r);
return;
}
void xc(int p,int l,int r){
if(lz1[p]==1&&lz2[p]==0)return;
int mid=(l+r)/2;
//左子树
sum[p*2]=sum[p*2]*lz1[p]%mod+lz2[p]*(ll)(mid-l+1)%mod;
lz1[p*2]*=lz1[p],lz2[p*2]*=lz1[p];
lz2[p*2]+=lz2[p];
sum[p*2]%=mod;lz1[p*2]%=mod;lz2[p*2]%=mod;
//右子树
sum[p*2+1]=sum[p*2+1]*lz1[p]%mod+lz2[p]*(ll)(r-mid)%mod;
lz1[p*2+1]*=lz1[p],lz2[p*2+1]*=lz1[p];
lz2[p*2+1]+=lz2[p];
sum[p*2+1]%=mod;lz1[p*2+1]%=mod;lz2[p*2+1]%=mod;
lz1[p]=1,lz2[p]=0;
return;
}
void insert1(int p,int l,int r,int l1,int r1){//区间加
if(l==l1&&r1==r){
sum[p]+=(ll)(r-l+1)*(ll)a3;sum[p]%=mod;
lz2[p]+=(ll)a3;lz2[p]%=mod;
return;
}
xc(p,l,r);
int mid=(l+r)/2;
if(r1<=mid)insert1(p*2,l,mid,l1,r1);
else if(mid<l1)insert1(p*2+1,mid+1,r,l1,r1);
else insert1(p*2,l,mid,l1,mid),insert1(p*2+1,mid+1,r,mid+1,r1);
sum[p]=sum[p*2]+sum[p*2+1];sum[p]%=mod;
return;
}
void insert2(int p,int l,int r,int l1,int r1){//区间乘
if(l==l1&&r1==r){
sum[p]*=(ll)a3;sum[p]%=mod;
lz1[p]*=(ll)a3;lz1[p]%=mod;
lz2[p]*=(ll)a3;lz2[p]%=mod;
return;
}
xc(p,l,r);
int mid=(l+r)/2;
if(r1<=mid)insert2(p*2,l,mid,l1,r1);
else if(mid<l1)insert2(p*2+1,mid+1,r,l1,r1);
else insert2(p*2,l,mid,l1,mid),insert2(p*2+1,mid+1,r,mid+1,r1);
sum[p]=sum[p*2]+sum[p*2+1];sum[p]%=mod;
return;
}
ll getsum(int p,int l,int r,int l1,int r1){
if(l==l1&&r==r1)return sum[p];
xc(p,l,r);
int mid=(l+r)/(ll)2;
if(r1<=mid)return getsum(p*2,l,mid,l1,r1);
if(mid<l1)return getsum(p*2+1,mid+1,r,l1,r1);
return (getsum(p*2,l,mid,l1,mid)+getsum(p*2+1,mid+1,r,mid+1,r1))%mod;
}
int main(){
freopen("easilysegmenttree.in","r",stdin);
freopen("easilysegmenttree.out","w",stdout);
scanf("%d%d%lld",&n,&m,&mod);
build(1,1,n);
while(m--){
scanf("%d%d%d",&s,&a1,&a2);
if(s==1){
scanf("%d",&a3);
insert1(1,1,n,a1,a2);
}
if(s==2){
scanf("%d",&a3);
insert2(1,1,n,a1,a2);
}
if(s==3)printf("%lld\n",(getsum(1,1,n,a1,a2)%mod+mod)%mod);
}
return 0;
}