博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj1798][Ahoi2009]Seq 维护序列seq
阅读量:5235 次
发布时间:2019-06-14

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

题意:给定一个序列,要支持区间加,区间乘,区间求和   $n,m\leqslant 100000$

题解:线段树练练手

#include
#include
#define MN 100000#define ll long longusing namespace std;inline int read(){ int x = 0 , f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x * f;}int n,m,s[MN+5],mod;struct TREE{ int l,r;ll x,ad,val;}T[MN*8+5];void pushdown(int x){ int l=x<<1,r=x<<1|1; if(T[x].val!=1) { T[l].ad*=T[x].val;T[r].ad*=T[x].val; T[l].val*=T[x].val;T[r].val*=T[x].val; T[l].ad%=mod;T[r].ad%=mod; T[l].val%=mod;T[r].val%=mod; } if(T[x].ad) { T[l].ad=(T[l].ad+T[x].ad)%mod; T[r].ad=(T[r].ad+T[x].ad)%mod; } T[l].x=(T[l].x*T[x].val%mod+1LL*(T[l].r-T[l].l+1)*T[x].ad)%mod; T[r].x=(T[r].x*T[x].val%mod+1LL*(T[r].r-T[r].l+1)*T[x].ad)%mod; T[x].val=1;T[x].ad=0;}void build(int x,int l,int r){ T[x].val=1; if((T[x].l=l)==(T[x].r=r)) {T[x].x=s[l];return;} int mid=l+r>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r); T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;}void modify(int x,int l,int r,ll ad){ pushdown(x); if(T[x].l==l&&T[x].r==r) { T[x].ad+=ad;T[x].x+=1LL*(r-l+1)*ad; T[x].x%=mod;T[x].ad%=mod; return; } int mid=T[x].l+T[x].r>>1; if(r<=mid)modify(x<<1,l,r,ad); else if(l>mid) modify(x<<1|1,l,r,ad); else {modify(x<<1,l,mid,ad);modify(x<<1|1,mid+1,r,ad);} T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;}void renew(int x,int l,int r,ll val){ pushdown(x); if(T[x].l==l&&T[x].r==r) { T[x].val*=val;T[x].val%=mod; T[x].x*=val;T[x].x%=mod; return; } int mid=T[x].l+T[x].r>>1; if(r<=mid)renew(x<<1,l,r,val); else if(l>mid) renew(x<<1|1,l,r,val); else {renew(x<<1,l,mid,val);renew(x<<1|1,mid+1,r,val);} T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;}ll query(int x,int l,int r){ pushdown(x); if(T[x].l==l&&T[x].r==r)return T[x].x; int mid=T[x].l+T[x].r>>1; if(r<=mid) return query(x<<1,l,r); else if(l>mid) return query(x<<1|1,l,r); else return (query(x<<1,l,mid)+query(x<<1|1,mid+1,r))%mod;}int main(){ n=read();mod=read(); for(int i=1;i<=n;i++)s[i]=read(); build(1,1,n); m=read(); for(int i=1;i<=m;i++) { int op=read(),l=read(),r=read(); if(op==3) printf("%d\n",(int)query(1,l,r)); else { int x=read(); if(op==2) modify(1,l,r,x); else renew(1,l,r,x); } } return 0;}

 

转载于:https://www.cnblogs.com/FallDream/p/bzoj1798.html

你可能感兴趣的文章
python3--算法基础:二分查找/折半查找
查看>>
Perl IO:随机读写文件
查看>>
转:基于用户投票的排名算法系列
查看>>
WSDL 详解
查看>>
[转]ASP数组全集,多维数组和一维数组
查看>>
C# winform DataGridView 常见属性
查看>>
逻辑运算和while循环.
查看>>
Nhiberate (一)
查看>>
c#后台计算2个日期之间的天数差
查看>>
安卓开发中遇到的小问题
查看>>
ARTS打卡第3周
查看>>
linux后台运行和关闭SSH运行,查看后台任务
查看>>
cookies相关概念
查看>>
CAN总线波形中ACK位电平为什么会偏高?
查看>>
MyBatis课程2
查看>>
桥接模式-Bridge(Java实现)
查看>>
svn客户端清空账号信息的两种方法
查看>>
springboot添加servlet的两种方法
查看>>
java的Array和List相互转换
查看>>
layui父页面执行子页面方法
查看>>