BZOJ1798 AHOI2009 维护数列
1798: [Ahoi2009]Seq 维护序列seq
Time Limit: 30 Sec Memory Limit: 64 MB
Description
Input
Output
Sample Input
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
Sample Output
35
8
HINT
【样例说明】
初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。
测试数据规模如下表所示
数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
迷醉线段树题。
这特么明显的线段树裸题,10w的数据,多组询问,支持区间修改和求和。
所以就是在lazy标记上做文章。
维护两个lazy标记,一个乘一个加。
因为要满足运算符优先级,所以乘法必须马上实现在加法上。
也就是说乘法的时候把加法的lazy也乘一遍。
所以lazy的乘法操作都是当前节点已经搞完了的。
那么lazy的下放就是要先乘再加了,不然会乘重复。
理清楚优先级的限制之后很好做的。(真的吗?)
反正我感觉乘的lazy就是加的lazy的lazy,除了一些维护答案的地方外... ...
感觉越说越不清楚,代码糊上。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define ls (x<<1)
#define rs (x<<1|1)
#define LL long long int
#define dob double
using namespace std; const int N = 100010;
int n,P,m,T[N<<2],lazy_A[N<<2],lazy_M[N<<2]; int gi()
{
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
} inline void build(int x,int l,int r){
if(l==r){T[x]=gi();return;}
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
T[x]=(T[ls]+T[rs])%P;
lazy_A[x]=0;lazy_M[x]=1;
} inline void down(int x,int l,int r){
int mid=(l+r)>>1;
T[ls]=(1ll*T[ls]*lazy_M[x]+1ll*(mid-l+1)*lazy_A[x])%P;
T[rs]=(1ll*T[rs]*lazy_M[x]+1ll*(r-mid)*lazy_A[x])%P;
lazy_M[ls]=(1ll*lazy_M[ls]*lazy_M[x])%P;
lazy_M[rs]=(1ll*lazy_M[rs]*lazy_M[x])%P;
lazy_A[ls]=(1ll*lazy_A[ls]*lazy_M[x]+1ll*lazy_A[x])%P;
lazy_A[rs]=(1ll*lazy_A[rs]*lazy_M[x]+1ll*lazy_A[x])%P;
lazy_A[x]=0;lazy_M[x]=1;
return;
} inline void Mul(int x,int l,int r,int xl,int xr,int v){
if(l==xl && r==xr){
lazy_A[x]=1ll*lazy_A[x]*v%P;
lazy_M[x]=1ll*lazy_M[x]*v%P;
T[x]=1ll*T[x]*v%P;
return;
}
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)Mul(ls,l,mid,xl,xr,v);
else if(xl>mid)Mul(rs,mid+1,r,xl,xr,v);
else Mul(ls,l,mid,xl,mid,v),Mul(rs,mid+1,r,mid+1,xr,v);
T[x]=(T[ls]+T[rs])%P;
} inline void Add(int x,int l,int r,int xl,int xr,int v){
if(l==xl && r==xr){
lazy_A[x]=(lazy_A[x]+v)%P;
T[x]=(1ll*T[x]+1ll*(r-l+1)*v)%P;
return;
}
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)Add(ls,l,mid,xl,xr,v);
else if(xl>mid)Add(rs,mid+1,r,xl,xr,v);
else Add(ls,l,mid,xl,mid,v),Add(rs,mid+1,r,mid+1,xr,v);
T[x]=(T[ls]+T[rs])%P;
} inline int query(int x,int l,int r,int xl,int xr){
if(l==xl && r==xr)return T[x];
down(x,l,r);
int mid=(l+r)>>1;
if(xr<=mid)return query(ls,l,mid,xl,xr);
else if(xl>mid)return query(rs,mid+1,r,xl,xr);
else return (query(ls,l,mid,xl,mid)+query(rs,mid+1,r,mid+1,xr))%P;
} int main()
{
n=gi();P=gi();
build(1,1,n);
m=gi();
while(m--){
int type=gi();
if(type==1){
int l=gi(),r=gi(),c=gi();
Mul(1,1,n,l,r,c);
}
if(type==2){
int l=gi(),r=gi(),c=gi();
Add(1,1,n,l,r,c);
}
if(type==3){
int l=gi(),r=gi();
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}
BZOJ1798 AHOI2009 维护数列的更多相关文章
- bzoj1798 [Ahoi2009]维护序列
Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- 【线段树】Bzoj1798 [AHOI2009] 维护序列
Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- BZOJ1798[Ahoi2009]维护序列——线段树
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 5504 Solved: 1937[Submit ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
- [洛谷P2023] [AHOI2009]维护序列
洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...
- 洛谷 P2023 [AHOI2009]维护序列
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- 【bzoj1500】 noi2005—维护数列
http://www.lydsy.com/JudgeOnline/problem.php?id=1500 (题目链接) 题意 要求维护数列,操作有区间删除,区间插入,区间反转,区间修改,区间求和,求最 ...
随机推荐
- [flask/python/web] 解析flask web开发(Miguel著)一书第11章主页不显示博文表单的问题
---------------------------------------------以下内容2017.7.14更新---------------------------------------- ...
- 从零开始,轻松搞定SpringCloud微服务系列
本系列博文目录 [微服务]之一:从零开始,轻松搞定SpringCloud微服务系列–开山篇(spring boot 小demo) [微服务]之二:从零开始,轻松搞定SpringCloud微服务系列–注 ...
- 小白关于python 对象和内存的关系的一些感悟和疑惑,望大神指教
首先你输入了一个字符串,这个字符串是有大小的,电脑将其放在内存中,自动给其一个起始指针指向这个字符串的首位置,然后,你将这个字符串赋值给一个变量,这个对象又在内存中开辟出一个空间,这个变量会自动连接这 ...
- 【Android源码解析】View.post()到底干了啥
emmm,大伙都知道,子线程是不能进行 UI 操作的,或者很多场景下,一些操作需要延迟执行,这些都可以通过 Handler 来解决.但说实话,实在是太懒了,总感觉写 Handler 太麻烦了,一不小心 ...
- 深度解剖sesssion运行原理
已经大半年没有更新博客了,一方面有比博客更重要的事情要做,另外一方面也没有时间来整理知识,所以希望在接下来的日子里面能够多多的写博客来与大家交流 什么是session session的官方定义是:Se ...
- python的简介及入门
前言 为何使用Python Python 是一种效率极高的语言.与其他众多的语言相比,实现相同功能,使用Python编写的程序包含的代码更少.Python的语法简单,易上手,使用Python编写的代码 ...
- 【算法】二叉查找树实现字典API
参考资料 <算法(java)> — — Robert Sedgewick, Kevin Wayne <数据结构> ...
- java多线程编程核心技术——第三章
第一节等待/通知机制 1.1不使用等待/通知机制实现线程间的通讯 1.2什么是等待/通知机制 1.3等待/通知机制的实现 1.4方法wait()锁释放与notify()锁不释放 1.5当interru ...
- Linux中如何恢复rm命令误删除的文件之extundelete编译安装及使用
1.下载extundelete包,安装依赖 我用的是Centos系统,在安装extundelete之前需要安装e2fsprogs,e2fsprogs-libs,e2fsprogs-devel. yum ...
- OpenXml读取word内容(三)
内容和表格内容一起读: word内容: 代码: public static void ReadWordByOpenXml(string path) { using (WordprocessingDoc ...