洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列
题目描述
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
输入输出格式
输入格式:
第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
输出格式:
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
输入输出样例
- 7 43
- 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
- 2
- 35
- 8
说明
【样例说明】
初始时数列为(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
Source: Ahoi 2009
解题思路
线段树的双lazy,我看了一个式子搞懂的——$$(ax+b)*c+d=(ac)\times x+(bc+d)$$
原来这个区间的数字是x,后来被打上了乘法标记a和加法标记b(乘法标记更先被打上),再后来,又打了一次乘法标记c,再打一次加法标记d。把这个式子展开,可以看出,在原先有乘法标记和加法标记的情况下,打新的乘法标记需要将原先的乘法标记和加法标记都乘上新标记c,但打加法标记时,直接加在已有的加法标记上就好(打上c时,原来的加法标记已经变成bc,所以打d时加在bc上就好)
源代码
- #include<stdio.h>
- #define lson(x) ((x)<<1)
- #define rson(x) (((x)<<1)|1)
- #define mid(x,y) ((x)+(y)>>1)
- #define mo(x) x%=p
- long long n,m,p;
- long long a[]={};
- struct segtree{
- int l,r;
- long long sum;
- }t[];
- long long lazya[];//加法懒标记
- long long lazym[];//乘法懒标记
- void maketree(int x,int l,int r)
- {
- t[x]={l,r,};
- lazym[x]=;lazya[x]=;
- if(l==r)
- {
- t[x].sum=a[l]%p;
- return;
- }
- maketree(lson(x),l,mid(l,r));
- maketree(rson(x),mid(l,r)+,r);
- t[x].sum=(t[lson(x)].sum+t[rson(x)].sum)%p;
- }
- void pushdown(int x)
- {
- int ls=lson(x),rs=rson(x);
- if(lazym[x]!=)
- {
- t[ls].sum*=lazym[x];mo(t[ls].sum);
- t[rs].sum*=lazym[x];mo(t[rs].sum);
- lazym[ls]*=lazym[x];mo(lazym[ls]);
- lazym[rs]*=lazym[x];mo(lazym[rs]);
- lazya[ls]*=lazym[x];mo(lazya[ls]);
- lazya[rs]*=lazym[x];mo(lazya[rs]);
- lazym[x]=;
- }
- if(lazya[x])
- {
- t[ls].sum+=(t[ls].r-t[ls].l+)*lazya[x];mo(t[ls].sum);
- t[rs].sum+=(t[rs].r-t[rs].l+)*lazya[x];mo(t[rs].sum);
- lazya[ls]+=lazya[x];mo(lazya[ls]);
- lazya[rs]+=lazya[x];mo(lazya[rs]);
- lazya[x]=;
- }
- }
- void upc(int x,int l,int r,long long k)
- {
- if(l>t[x].r||r<t[x].l)return;
- if(l<=t[x].l&&t[x].r<=r)
- {
- t[x].sum*=k;mo(t[x].sum);
- lazym[x]*=k;mo(lazym[x]);
- lazya[x]*=k;mo(lazya[x]);
- return;
- }
- pushdown(x);
- upc(lson(x),l,r,k);
- upc(rson(x),l,r,k);
- t[x].sum=t[lson(x)].sum+t[rson(x)].sum;mo(t[x].sum);
- }
- void upj(int x,int l,int r,long long k)
- {
- if(l>t[x].r||r<t[x].l)return;
- if(l<=t[x].l&&t[x].r<=r)
- {
- t[x].sum+=(t[x].r-t[x].l+)*k;mo(t[x].sum);
- lazya[x]+=k;mo(lazya[x]);
- return;
- }
- pushdown(x);
- upj(lson(x),l,r,k);
- upj(rson(x),l,r,k);
- t[x].sum=t[lson(x)].sum+t[rson(x)].sum;mo(t[x].sum);
- }
- long long query(int x,int l,int r)
- {
- if(l>t[x].r||r<t[x].l)return ;
- if(l<=t[x].l&&t[x].r<=r) return t[x].sum;
- pushdown(x);
- return (query(lson(x),l,r)%p+query(rson(x),l,r)%p)%p;
- }
- int main()
- {
- //freopen("test.in","r",stdin);
- scanf("%lld%lld",&n,&p);
- for(int i=;i<=n;i++)scanf("%lld",a+i);
- scanf("%lld",&m);
- maketree(,,n);
- for(long long i=,mode,x,y,k;i<=m;i++)
- {
- scanf("%lld",&mode);
- if(mode==)
- {
- scanf("%lld%lld%lld",&x,&y,&k);
- upc(,x,y,k);
- }
- else if(mode==)
- {
- scanf("%lld%lld%lld",&x,&y,&k);
- upj(,x,y,k);
- }
- else
- {
- scanf("%lld%lld",&x,&y);
- printf("%lld\n",query(,x,y));
- }
- }
- return ;
- }
洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列的更多相关文章
- 洛谷 P4093: bzoj 4553: [HEOI2016/TJOI2016]序列
题目传送门:洛谷P4093. 题意简述: 给定一个长度为 \(n\) 的序列 \(a\). 同时这个序列还可能发生变化,每一种变化 \((x_i,y_i)\) 对应着 \(a_{x_i}\) 可能变成 ...
- 1798. [AHOI2009]维护序列【线段树】
Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...
- bzoj 1798 Seq 维护序列seq —— 线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1798 这题还4A... 注意:cnt 从1开始:各种模 p:乘法标记初始值是 1:可能乘 0 ...
- 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)
洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...
- [洛谷P2023] [AHOI2009]维护序列
洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...
- 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)
洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...
- 洛谷 P2023 [AHOI2009]维护序列
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解
题目传送: P3373 [模板]线段树 2 P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...
随机推荐
- 【POJ 1475】 Pushing Boxes
[题目链接] http://poj.org/problem?id=1475 [算法] 双重BFS [代码] #include <algorithm> #include <bitset ...
- hdu3507Print Article(斜率优化dp)
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- html5的Form新特性
form新增的输入型控件: 名称 说明 图例 email 电子邮箱文本框,显示跟普通的没什么区别 tel 电话号码,pc端不会有明显的变化,但是移动端会自动切换键盘,输入有误不会阻止默认提交 u ...
- spring定时任务Cron时间设定
直接举例: 0 10 0 * *?分别对应的是 秒 分 时 日 月 周 年 秒(0–59)分钟(0–59)小时(0–23)日(1–31)月(1–12或JAN–DEC)周(1–7或SUN–SAT)年(1 ...
- 前端HTML中float学习笔记
float元素原本的作用是用来使文字包裹图片,现在人们更多的是用来进行布局(ps:有没有点滥用的意思) 也就是说本来你排好的界面设计,但是因为浮动会导致元素脱离文档流,使得其他非浮动的块级元素会无视这 ...
- 【Hexo】deploy出错的解决方法
.ERROR Deployer not found: git 执行npm install hexo-deployer-git --save .$ hexo d INFO Deploying: git ...
- 极客学院免费VIP
[手快福利]用我的链接注册极客学院,你我都能免费得30天VIP!6500+编程开发视频教程随便学,还能下载资料和源码 http://e.jikexueyuan.com/invite/index.htm ...
- iproute2和tc的高级路由用法
#Linux advanced router ip link show #显示链路 ip addr show #显示地址(或ifconfig) ip route show #显示路由(route -n ...
- C# 获得剪贴板内容和 richTextBox部分文本设置颜色
try { MemoryStream vMemoryStream = iData.GetData("Html Format") as MemoryStream; if (vMemo ...
- linux中tomcat启动脚本:关闭、发布、重启、测试是否成功
说明 在使用jenkins持续集成时,需要实现自动发布包到tomcat.该脚本实现了在jenkins将包发送到linux服务器上后的自动关闭.发布.启动.测试启动是否成功的过程 思路 该思路以tomc ...