bzoj1798 [Ahoi2009]维护序列
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
正解:线段树。
这题不难,但是容易出错,所以还是挺有意义的。
我们除了维护一个加法的标记以外,还要维护一个乘法的标记,当我们下放更新乘法标记时,被更新的那个区间的加法标记也要乘上对应的数(这个应该很显然吧。。)。并且我们下放的时候,要先下放乘法标记,再下放加法标记。于是我们就能完美地解决这题了。
- //It is made by wfj_2048~
- #include <algorithm>
- #include <iostream>
- #include <complex>
- #include <cstring>
- #include <cstdlib>
- #include <cstdio>
- #include <vector>
- #include <cmath>
- #include <queue>
- #include <stack>
- #include <map>
- #include <set>
- #define inf (1<<30)
- #define ls (x<<1)
- #define rs (x<<1|1)
- #define N (100010)
- #define il inline
- #define RG register
- #define ll long long
- #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
- using namespace std;
- ll sum[*N],m[*N],a[*N],n,Q,p;
- il ll gi(){
- RG ll x=,q=; RG char ch=getchar();
- while ((ch<'' || ch>'') && ch!='-') ch=getchar();
- if (ch=='-') q=-,ch=getchar();
- while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
- return q*x;
- }
- il void build(RG ll x,RG ll l,RG ll r){
- if (l==r){ sum[x]=gi(),m[x]=; return; }
- RG ll mid=(l+r)>>;
- build(ls,l,mid),build(rs,mid+,r);
- sum[x]=sum[ls]+sum[rs]; m[x]=;
- if (sum[x]>=p) sum[x]-=p; return;
- }
- il void pushdown(RG ll x,RG ll l,RG ll r){
- if (m[x]!=){
- sum[ls]*=m[x],sum[ls]%=p;
- sum[rs]*=m[x],sum[rs]%=p;
- m[ls]*=m[x],m[ls]%=p;
- m[rs]*=m[x],m[rs]%=p;
- a[ls]*=m[x],a[ls]%=p;
- a[rs]*=m[x],a[rs]%=p;
- m[x]=;
- }
- if (a[x]!=){
- RG ll mid=(l+r)>>;
- sum[ls]+=(mid-l+)*a[x],sum[ls]%=p;
- sum[rs]+=(r-mid)*a[x],sum[rs]%=p;
- a[ls]+=a[x]; if (a[ls]>=p) a[ls]-=p;
- a[rs]+=a[x]; if (a[rs]>=p) a[rs]-=p;
- a[x]=;
- }
- return;
- }
- il void mul(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr,RG ll c){
- if (xl<=l && r<=xr){
- sum[x]*=c,sum[x]%=p;
- m[x]*=c,m[x]%=p;
- a[x]*=c,a[x]%=p;
- return;
- }
- pushdown(x,l,r); RG ll mid=(l+r)>>;
- if (xr<=mid) mul(ls,l,mid,xl,xr,c);
- else if (xl>mid) mul(rs,mid+,r,xl,xr,c);
- else mul(ls,l,mid,xl,mid,c),mul(rs,mid+,r,mid+,xr,c);
- sum[x]=sum[ls]+sum[rs]; if (sum[x]>=p) sum[x]-=p; return;
- }
- il void add(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr,RG ll c){
- if (xl<=l && r<=xr){
- sum[x]+=(r-l+)*c,sum[x]%=p;
- a[x]+=c; if (a[x]>=p) a[x]-=p;
- return;
- }
- pushdown(x,l,r); RG ll mid=(l+r)>>;
- if (xr<=mid) add(ls,l,mid,xl,xr,c);
- else if (xl>mid) add(rs,mid+,r,xl,xr,c);
- else add(ls,l,mid,xl,mid,c),add(rs,mid+,r,mid+,xr,c);
- sum[x]=sum[ls]+sum[rs]; if (sum[x]>=p) sum[x]-=p; return;
- }
- il ll query(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr){
- if (xl<=l && r<=xr) return sum[x];
- pushdown(x,l,r); RG ll mid=(l+r)>>;
- if (xr<=mid) return query(ls,l,mid,xl,xr);
- else if (xl>mid) return query(rs,mid+,r,xl,xr);
- else return (query(ls,l,mid,xl,mid)+query(rs,mid+,r,mid+,xr))%p;
- }
- il void work(){
- n=gi(),p=gi(); build(,,n); Q=gi();
- for (RG ll i=,type,l,r,c;i<=Q;++i){
- type=gi(),l=gi(),r=gi();
- if (type==) c=gi(),mul(,,n,l,r,c);
- if (type==) c=gi(),add(,,n,l,r,c);
- if (type==) printf("%lld\n",query(,,n,l,r));
- }
- return;
- }
- int main(){
- File("seq");
- work();
- return ;
- }
bzoj1798 [Ahoi2009]维护序列的更多相关文章
- 【线段树】Bzoj1798 [AHOI2009] 维护序列
Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- BZOJ1798[Ahoi2009]维护序列——线段树
题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
- [Luogu 2023] AHOI2009 维护序列
[Luogu 2023] AHOI2009 维护序列 恕我冒昧这和线段树模板二有个琴梨区别? #include <cstdio> int n,m; long long p; class S ...
- [洛谷P2023] [AHOI2009]维护序列
洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...
- 洛谷 2023 [AHOI2009]维护序列
洛谷 2023 [AHOI2009]维护序列 洛谷原题传送门 这个题也是一道经典的线段树模版(其实洛谷的模版二改一下输入顺序就能AC),其中包括区间乘法修改.区间加法修改.区间查询三个操作. 线段树的 ...
- 洛谷 P2023 [AHOI2009]维护序列
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)
洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...
随机推荐
- MVC支付宝PC网站接口对接
PC网站支付接口,请参考支付宝官方文档:https://b.alipay.com/signing/productSet.htm?navKey=all 1.需要提供签约账号.商户密钥 2.代码实现: 支 ...
- 菜鸟Scrum敏捷实践系列(一)用户故事概念
菜鸟Scrum敏捷实践系列索引 菜鸟Scrum敏捷实践系列(一)用户故事概念 菜鸟Scrum敏捷实践系列(二)用户故事验收 菜鸟Scrum敏捷实践系列(三)用户故事的组织---功能架构的规划 敏捷开发 ...
- JQ万能轮播图
lunbotu.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- [译]Selenium Python文档:六、页面对象
本章是介绍页面对象设计模式的教程.一个页面对象代表了web应用用户接口的一片区域,你的测试代码将与之交互的. 使用页面对象模式的好处: 可以创建在多个测试样例中都可使用的可重用代码 减少重复性代码 如 ...
- iOS全角符与半角符之间的转换
iOS全角符与半角符之间的转换 相关资料: 函数『CFStringTransform』中文 详情: 问题 1.17-03-15,「有人在群里边问怎么把『半角』符字符串转换成『全角』字符串?」,百度的 ...
- UWP Composition API - New FlexGrid 锁定行列
如果之前看了 UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包 这篇的童鞋,针对VS2017,需要对应更新一下配置,需要的童鞋点 ...
- 自动部署Nginx和nfs并架设Nginx集群脚本
本人经过多次尝试,简单完成了自动部署Nginx和nfs脚本,并且能够自动部署web反向代理集群,下面详细的阐述一下本人的思路.(以下脚本本人处于初学阶段,写的并不是很完善,所以需要后期进行整理和修正, ...
- Ant.SOA微服务框架开源
开源地址:https://github.com/yuzd/AntServiceStack 框架特色0.Service Management(服务治理) 1.CodeGen Contract Fir ...
- 数字千分位处理,number.js,js保留两位,整数强制保留两位小数
杨龙飞 杨龙飞 杨龙飞 杨龙飞 杨龙飞 杨龙飞 官方文档:https://www.customd.com/articles/14/jquery-number-format-redux 1.千分位 $. ...
- Windows下检测文件名大小写是否匹配
跨平台开发有一个众所周知,但因为只是偶尔受到困扰,一般人不会在意的问题,就是windows对文件名大小写不敏感,而其他平台对文件名大小写敏感.因此可能出现在windows平台开发时一切正常,但部署/打 ...