【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 ...
随机推荐
- Environment类,获取程序所在机器信息
一.属性 CommandLine 获取该进程的命令行.CurrentDirectory 获取或设置当前工作目录的完全限定路径.ExitCode 获取或设置进程的退出代码.HasShutdownSta ...
- 文本处理命令--wc、sed
一.wc wc命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 测试文件内容: (my_python_env)[root@hadoop26 ~]# cat test hnlinu ...
- “requireJs前传”之为什么要用前端模块化?
对于没有接触过后台的前端同学想要理解模块化是很困难的,鉴于未来的趋势,以下是我转载的一篇文章,希望对大家有用! 特此声明:转载文章,不喜勿喷.和谐前端,世界和平!0.0 模块的写法 随着网站逐渐变成” ...
- 批量关闭 WordPress 的 Pingback 和 Trackback 功能
方法很简单,WordPress 后台即可实现,在设置-讨论中把"接收来自外部博客的引用通告(Pingback 和 Trackback)"这一项勾选去掉,保存设置.这样,以后新增的文 ...
- Ueditor防止代码自动清除
Ueditor功能真的很牛逼,可也有让人悲催的地方,尤其是自动清除代码,会将你默认的div标签改成p,挺让人闹心的,不过Ueditor的开发人员还是满热心的,搜遍网上无答案的时候,问了下他们,解决了 ...
- 了解Unix进程(1)
今天瞎看 看到一本了解Unix进程 -- 理解UNIX进程 的书 不错,可以看看,使用的ruby语言,第一章讲的是一些基础的知识 1.输出进程号和父进程号: puts Process.pid # 得到 ...
- JAVA里的字符串,String 类简单介绍
http://www.360doc.com/content/14/1107/23/17130779_423471141.shtml
- PuTTY 中文教程
PuTTY 中文教程 更新记录 2006-11-29初步完成想写的这些东西 2007-06-11PuTTY 的最新版本到了0.6:修改了一下 SSH 隧道:添加了 SSH 反向隧道:添加了用 SSH ...
- Linux驱动开发之字符设备模板
/***************************** ** 驱动程序模板* 版本:V1* 使用方法(末行模式下):* :%s/xxx/"你的驱动名称"/g********* ...
- 基于opencv 的图片模糊判断代码
#include"cv.h" #include"highgui.h" #include<iostream> using namespace s ...