洛谷 P3373 【模板】线段树 2

对懒标记的理解更深入了
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
const int N = 1e5+10;
int n,m,p;
int a[N];
struct NODE{
int l,r;
int sum;
int add,mul;
}tr[N*4];
void pushup(int u){
tr[u].sum=(tr[u<<1].sum+tr[u<<1|1].sum)%p;
}
void pushdown(int u){
int x=u<<1,y=u<<1|1;
tr[x].sum=(tr[x].sum*tr[u].mul+tr[u].add*(tr[x].r-tr[x].l+1))%p;
tr[x].add=(tr[x].add*tr[u].mul+tr[u].add)%p;
tr[x].mul=(tr[x].mul*tr[u].mul)%p;
tr[y].sum=(tr[y].sum*tr[u].mul+tr[u].add*(tr[y].r-tr[y].l+1))%p;
tr[y].add=(tr[y].add*tr[u].mul+tr[u].add)%p;
tr[y].mul=(tr[y].mul*tr[u].mul)%p;
tr[u].add=0;
tr[u].mul=1;
}
void build(int u,int l,int r){
if(l==r){
tr[u]={l,l,a[l],0,1};
return;
}
tr[u].l=l,tr[u].r=r,tr[u].add=0,tr[u].mul=1;
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
int query(int u,int l,int r){
if(l<=tr[u].l && r>=tr[u].r) return tr[u].sum;
else{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid) return query(u<<1,l,r);
else if(l>mid) return query(u<<1|1,l,r);
else{
int suml=query(u<<1,l,r),sumr=query(u<<1|1,l,r);
return suml+sumr;
}
}
}
void modify(int u,int l,int r,int d,int flag){
if(l<=tr[u].l && r>=tr[u].r){
if(flag){
tr[u].sum=(tr[u].sum+(tr[u].r-tr[u].l+1)*d)%p;
tr[u].add=(tr[u].add+d)%p;
}
else{
tr[u].sum=tr[u].sum*d%p;
tr[u].add=tr[u].add*d%p;
tr[u].mul=tr[u].mul*d%p;
}
}
else{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid) modify(u<<1,l,r,d,flag);
else if(l>mid) modify(u<<1|1,l,r,d,flag);
else{
modify(u<<1,l,r,d,flag);
modify(u<<1|1,l,r,d,flag);
}
pushup(u);
}
}
signed main(){
cin>>n>>m>>p;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
int op;
while(m--){
scanf("%lld",&op);
if(op==3){
int l,r;
cin>>l>>r;
cout<<query(1,l,r)%p<<endl;
}
else{
int l,r,d;
cin>>l>>r>>d;
if(op==1) modify(1,l,r,d,0);
else modify(1,l,r,d,1);
}
}
return 0;
}

本文作者:xhy666

本文链接:https://www.cnblogs.com/xhy666/p/16387446.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xhy666  阅读(36)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起