博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【模板】线段树 2
阅读量:4947 次
发布时间:2019-06-11

本文共 2538 字,大约阅读时间需要 8 分钟。

和另外一个版子没太大区别,再开一组懒惰标记即可

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;long long c[500010];long long p;struct sgt{ long long sum[2000010]; long long addv[2000010]; long long mulv[2000010]; void build(int o,int l,int r){ addv[o]=0; mulv[o]=1; if(l==r)sum[o]=c[l]; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; build(lson,l,mid); build(rson,mid+1,r); sum[o]=(sum[lson]+sum[rson])%p; } } void push_down(int o,int l,int r,int mid,int lson,int rson){ mulv[lson]=(mulv[lson]*mulv[o])%p; mulv[rson]=(mulv[rson]*mulv[o])%p; addv[lson]=(addv[lson]*mulv[o])%p; addv[rson]=(addv[rson]*mulv[o])%p; sum[lson]=(sum[lson]*mulv[o])%p; sum[rson]=(sum[rson]*mulv[o])%p; mulv[o]=1; addv[lson]=(addv[lson]+addv[o])%p; addv[rson]=(addv[rson]+addv[o])%p; sum[lson]=(sum[lson]+(mid-l+1)*addv[o])%p; sum[rson]=(sum[rson]+(r-mid)*addv[o])%p; addv[o]=0; } void addall(int o,int l,int r,int a,int b,int x){ if(l>=a && r<=b){ addv[o]=(addv[o]+x)%p; sum[o]=(sum[o]+(r-l+1)*x)%p; return; } else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; if(mulv[o]!=1 || addv[o])push_down(o,l,r,mid,lson,rson); if(a<=mid)addall(lson,l,mid,a,b,x); if(b>mid)addall(rson,mid+1,r,a,b,x); sum[o]=(sum[lson]+sum[rson])%p; } } void mulall(int o,int l,int r,int a,int b,int x){ if(l>=a && r<=b){ mulv[o]=(mulv[o]*x)%p; addv[o]=(addv[o]*x)%p; sum[o]=(sum[o]*x)%p; return; } else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; if(mulv[o]!=1 || addv[o])push_down(o,l,r,mid,lson,rson); if(a<=mid)mulall(lson,l,mid,a,b,x); if(b>mid)mulall(rson,mid+1,r,a,b,x); sum[o]=(sum[lson]+sum[rson])%p; } } long long query(int o,int l,int r,int a,int b){ if(l>=a && r<=b)return sum[o]%p; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; long long ans=0; if(mulv[o]!=1 || addv[o])push_down(o,l,r,mid,lson,rson); if(a<=mid)ans+=query(lson,l,mid,a,b); if(b>mid)ans+=query(rson,mid+1,r,a,b); return ans%p; } }};sgt tree;int n,m,i,f;int x,y;long long k;int main(){ scanf("%d%d%d",&n,&m,&p); for(i=1;i<=n;i++)scanf("%d",&c[i]); tree.build(1,1,n); for(i=1;i<=m;i++){ scanf("%d",&f); switch(f){ case 1:{ scanf("%d%d%d",&x,&y,&k); tree.mulall(1,1,n,x,y,k); break; } case 2:{ scanf("%d%d%d",&x,&y,&k); tree.addall(1,1,n,x,y,k); break; } case 3:{ scanf("%d%d",&x,&y); printf("%lld\n",tree.query(1,1,n,x,y)); break; } } } return 0;}

  

转载于:https://www.cnblogs.com/ainiyuling/p/11206934.html

你可能感兴趣的文章
linux下mail命令使用
查看>>
晚安西南-----远控房魅影二之FKQ1440-14
查看>>
【例题】一笔画问题
查看>>
cuda8.0 + cudnn6 + tensorflow1.4 xing
查看>>
C# 字符串转换值类型
查看>>
nginx rewrite
查看>>
Oracle 身份验证方式
查看>>
整体贪心 + 局部01背包 之 hdu 2546
查看>>
浏览器渲染和服务器渲染区别
查看>>
sublime 自定义配置python开发环境
查看>>
打印图形
查看>>
pod
查看>>
POJ 1603 Risk
查看>>
SpringMVC源代码学习外传(二)如何在重定向时传递参数&FlashMap
查看>>
写在最前面
查看>>
delphi edit编辑框使用
查看>>
洛谷 1019 单词接龙
查看>>
c++,虚函数,单继承,多继承虚表剖析
查看>>
python的Windows下的安装
查看>>
修改AdminLTE左侧菜单展开延迟
查看>>