bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)
2016-03-29 19:26
525 查看
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1798
【题意】
给定一个序列,要求提供区间乘/加,以及区间求和的操作
【思路】
线段树+传标。
下传标记的方式可以类比这里 click here
【代码】
P.S.我竟然蛋疼的存了一个v,还一本正经地累计到sum里 <_<
http://www.lydsy.com/JudgeOnline/problem.php?id=1798
【题意】
给定一个序列,要求提供区间乘/加,以及区间求和的操作
【思路】
线段树+传标。
下传标记的方式可以类比这里 click here
【代码】
#include<set> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) #define FOR(a,b,c) for(int a=(b);a<=(c);a++) using namespace std; typedef long long ll; const int N = 2e5+10; ll read() { char c=getchar(); ll f=1,x=0; while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } int MOD ; struct Tnode { int u,l,r; ll sum,add,mul; void mulv(ll x) ; void addv(ll x) ; void pushdown() ; void maintain() ; } T[N<<2] ; void Tnode::mulv(ll x) { mul=(mul*x)%MOD; sum=(sum*x)%MOD; add=(add*x)%MOD; } void Tnode::addv(ll x) { sum=(sum+(r-l+1)*x)%MOD; add=(add+x)%MOD; } void Tnode::pushdown() { if(mul!=1) { T[u<<1].mulv(mul); T[u<<1|1].mulv(mul); mul=1; } if(add) { T[u<<1].addv(add); T[u<<1|1].addv(add); add=0; } } void Tnode::maintain() { sum=(T[u<<1].sum+T[u<<1|1].sum)%MOD; } void update(int u,int L,int R,int x,int flag) { T[u].pushdown(); if(L<=T[u].l&&T[u].r<=R) { if(flag==0) T[u].addv(x); else T[u].mulv(x); } else { int mid=T[u].l+T[u].r>>1; if(L<=mid) update(u<<1,L,R,x,flag); if(mid<R) update(u<<1|1,L,R,x,flag); T[u].maintain(); } } ll query(int u,int L,int R) { T[u].pushdown(); if(L<=T[u].l&&T[u].r<=R) return T[u].sum; else { int mid=T[u].l+T[u].r>>1; ll ans=0; if(L<=mid) ans=(ans+query(u<<1,L,R))%MOD; if(mid<R) ans=(ans+query(u<<1|1,L,R))%MOD; return ans; } } int n,m; ll a ; void build(int u,int l,int r) { T[u]=(Tnode){u,l,r,0,0,1}; if(l==r) { T[u].sum=a[l]%MOD; return ; } else { int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); T[u].maintain(); } } /* Debug int print(int u) { T[u].pushdown(); if(T[u].l==T[u].r) printf("%d,%d\n",T[u].l,T[u].v); else { print(u<<1),print(u<<1|1); } } */ int main() { // freopen("in.in","r",stdin); // freopen("out.out","w",stdout); n=read(),MOD=read(); FOR(i,1,n) a[i]=read(); build(1,1,n); m=read(); int op,l,r,x; FOR(i,1,m) { op=read(),l=read(),r=read(); if(op==1) { x=read(); update(1,l,r,x,1); } else if(op==2) { x=read(); update(1,l,r,x,0); } else { printf("%lld\n",query(1,l,r)); } } return 0; }
P.S.我竟然蛋疼的存了一个v,还一本正经地累计到sum里 <_<
相关文章推荐
- 升级Linux内核
- 让eclipse自动向tomcat导入lib
- Linux 内核源代码情景分析 chap 2 存储管理 (三)
- Linux查看CPU信息、机器型号等硬件信息
- 在linux上配置unixODBC和FreeTDS访问MS SQL Server.
- 秒杀系统架构分析与实战-转
- Ubuntu Apache 不同端口监听不同站点
- 【HDU】 1011 Starship Troopers
- 搭建git私有服务器及同步更新自己网站的文件
- Tomcat servlet不工作问题解决
- 中小型网站架构分析及优化
- opencv人脸识别训练
- oslab的环境配置
- Linux下面如何运行.sh文件
- apache使用jk插件集成tomcat_apachez
- 讲解Linux中常见文件类型
- 架构设计:负载均衡层设计方案(4)——LVS原理
- java转换json需要导入的jar包,org/apache/commons/lang/exception/NestableRuntimeException
- Linux shell 脚本语法总结
- linux嵌入式: 实现自己的tree命令