【BZOJ】【1798】【AHOI2009】Seq维护序列
线段树
属于线段树中级应用吧……
要打两种标记:乘法和加法标记。一开始我想着可以像只有加法标记那样,永不下传,查询的时候依次累加就好了。后来发现不会写……只好每次update的时候……遇到标记!下传!query的时候遇到标记!下传!暴力地来搞……
然后说下下传的细节:先传乘法,后传加法。因为传乘法标记的时候要连sum带add都要一起乘,如果先传add就会多乘……
/**************************************************************
Problem: 1798
User: Tunix
Language: C++
Result: Accepted
Time:3868 ms
Memory:6748 kb
****************************************************************/ //BZOJ 1798
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
//using namespace std;
const int N=;
typedef long long LL;
//#define debug
int n,m,P,a[N];
int mul[N<<],add[N<<],sum[N<<]; void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<'' || ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>='' && ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
#define mid (l+r>>1)
#define L (o<<1)
#define R (o<<1|1) void Push_down(int o,int l,int r){
if (mul[o]!=){
add[L]=((LL)add[L]*mul[o])%P; add[R]=((LL)add[R]*mul[o])%P;
mul[L]=((LL)mul[L]*mul[o])%P; mul[R]=((LL)mul[R]*mul[o])%P;
mul[o]=;
}
if (add[o]!=){
add[L]=((LL)add[L]+add[o])%P; add[R]=((LL)add[R]+add[o])%P;
add[o]=;
}
}
void Push_up(int o,int l,int r){
if (l<r) sum[o]=(sum[L]+sum[R])%P; else sum[o]=;
sum[o]=((LL)sum[o]*mul[o]+(LL)add[o]*(r-l+))%P;
}
void build(int o,int l,int r){
if (l==r) add[o]=sum[o]=a[l],mul[o]=;
else{
build(L,l,mid);
build(R,mid+,r);
add[o]=; mul[o]=;
Push_up(o,l,r);
}
}
int ql,qr;
void update_add(int o,int l,int r,int v){
if (ql<=l && qr>=r)
add[o]=((LL)add[o]+v)%P;
else{
if (mul[o]!= || add[o]) Push_down(o,l,r);
if (ql<=mid) update_add(L,l,mid,v); else Push_up(L,l,mid);
if (qr>mid) update_add(R,mid+,r,v); else Push_up(R,mid+,r);
}
Push_up(o,l,r);
}
void update_mul(int o,int l,int r,int v){
if (ql<=l && qr>=r)
mul[o]=((LL)mul[o]*v)%P,add[o]=(LL)add[o]*v%P;
else{
if (mul[o]!= || add[o]) Push_down(o,l,r);
if (ql<=mid) update_mul(L,l,mid,v); else Push_up(L,l,mid);
if (qr>mid) update_mul(R,mid+,r,v); else Push_up(R,mid+,r);
}
Push_up(o,l,r);
}
int sumv;
void query(int o,int l,int r){
if (ql<=l && qr>=r)
sumv=((LL)sumv+sum[o])%P;
else{
if (mul[o]!= || add[o]) {Push_down(o,l,r); Push_up(L,l,mid); Push_up(R,mid+,r);}
if (ql<=mid) query(L,l,mid);
if (qr>mid) query(R,mid+,r);
}
}
int ans[N],cnt=;
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
read(n); read(P);
F(i,,n) read(a[i]);
// F(i,1,n) printf("%d ",a[i]);
// printf("\n");
build(,,n); read(m);
// printf("m=%d\n",m);
int c,v;
F(i,,m){
read(c); read(ql); read(qr);
// printf("c=%d\n",c);
switch(c){
case : read(v); update_mul(,,n,v); break;
case : read(v); update_add(,,n,v); break;
case : sumv=; query(,,n); ans[cnt++]=sumv;break;
}
}
rep(i,cnt-) printf("%d\n",ans[i]);
printf("%d",ans[cnt-]);
return ;
}
【BZOJ】【1798】【AHOI2009】Seq维护序列的更多相关文章
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 7773 Solved: 2792[Submit ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
- bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...
- BZOJ 1798 AHOI2009 Seq 维护序列 线段树
题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...
- bzoj 1798 [Ahoi2009]Seq 维护序列seq
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 线段树区间更新: 1. 区间同同时加上一个数 2. 区间同时乘以一个数 #inclu ...
- bzoj 1798 [Ahoi2009]Seq 维护序列seq ——线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1798 先乘后加,就可给加法标记乘上乘法标记. 注意可能有 *0 的操作,所以 pshd 时不 ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树乘法加法的混合操作)
题目:点击打开链接 大意:一个数组.三个操作.第一种是区间[a,b]每一个数乘乘,另外一种是区间[a,b]每一个数加c,第三种是查询[a,b]区间的和并对p取摸. 两种操作就不能简单的仅仅往下传 ...
- 1798: [Ahoi2009]Seq 维护序列seq
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 2930 Solved: 1087[Submit ...
随机推荐
- mariadb日志学习笔记
MySQL日志: 查询日志:query log 慢查询日志: 查询执行时长超过指定时长的查询操作所记录的日志 slow query log 错误日志:包含了服务器启动和关闭的正常信息 二进制日志:包含 ...
- Sublime Text生成html标签快捷键
Emmet Documentation Syntax Child: > nav>ul>li <nav> <ul> <li></li> ...
- scala学习资料
强烈推荐一个s在线学习scala的网站: http://zh.scala-tour.com/#/overview
- 算法系列9《MD5》
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法),主流编程语言普遍已有MD5实现. ...
- linux之iptables总结
netfilter/iptables概述: netfilter/iptables是Linux内核防火墙架构,由netfilter实现功能,由iptables提供接口. iptables ...
- Knockout应用开发指南 第一章:入门
2011-11-21 14:20 by 汤姆大叔, 20165 阅读, 17 评论, 收藏, 编辑 1 Knockout简介 (Introduction) Knockout是一个轻量级的UI类 ...
- ASP.NET MVC掉过的坑_MVC初识及MVC应用程序结构
APS.Net MVC 浅谈[转] 来自MSDN 点击访问 MVC 理论结构 模型-视图-控制器 (MVC) 体系结构模式将应用程序分成三个主要组件:模型.视图和控制器. ASP.NET MVC 框架 ...
- [转]每天一个linux命令目录
[转]每天一个linux命令目录 http://www.cnblogs.com/peida/archive/2012/12/05/2803591.html 开始详细系统的学习linux常用命令,坚持每 ...
- opencv车道线检测
opencv车道线检测 完成的功能 图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像 反透视变换:用的是老师给的视频,没有对应的变换矩阵.所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视 ...
- forword属性
forword属性 2013年7月8日 15:07 Name: Forward的名字,与mapping.findForward方法传入的值相同. Path: 请求转发的页面路径 Redirect: 请 ...