题目描述

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为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,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

输入输出样例

输入样例#1:

  1. 7 43
  2. 1 2 3 4 5 6 7
  3. 5
  4. 1 2 5 5
  5. 3 2 4
  6. 2 3 7 9
  7. 3 1 3
  8. 3 4 7
输出样例#1:

  1. 2
  2. 35
  3. 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上就好)

源代码

  1. #include<stdio.h>
  2. #define lson(x) ((x)<<1)
  3. #define rson(x) (((x)<<1)|1)
  4. #define mid(x,y) ((x)+(y)>>1)
  5. #define mo(x) x%=p
  6. long long n,m,p;
  7. long long a[]={};
  8. struct segtree{
  9. int l,r;
  10. long long sum;
  11. }t[];
  12. long long lazya[];//加法懒标记
  13. long long lazym[];//乘法懒标记
  14. void maketree(int x,int l,int r)
  15. {
  16. t[x]={l,r,};
  17. lazym[x]=;lazya[x]=;
  18. if(l==r)
  19. {
  20. t[x].sum=a[l]%p;
  21. return;
  22. }
  23. maketree(lson(x),l,mid(l,r));
  24. maketree(rson(x),mid(l,r)+,r);
  25. t[x].sum=(t[lson(x)].sum+t[rson(x)].sum)%p;
  26. }
  27. void pushdown(int x)
  28. {
  29. int ls=lson(x),rs=rson(x);
  30. if(lazym[x]!=)
  31. {
  32. t[ls].sum*=lazym[x];mo(t[ls].sum);
  33. t[rs].sum*=lazym[x];mo(t[rs].sum);
  34. lazym[ls]*=lazym[x];mo(lazym[ls]);
  35. lazym[rs]*=lazym[x];mo(lazym[rs]);
  36. lazya[ls]*=lazym[x];mo(lazya[ls]);
  37. lazya[rs]*=lazym[x];mo(lazya[rs]);
  38. lazym[x]=;
  39. }
  40. if(lazya[x])
  41. {
  42. t[ls].sum+=(t[ls].r-t[ls].l+)*lazya[x];mo(t[ls].sum);
  43. t[rs].sum+=(t[rs].r-t[rs].l+)*lazya[x];mo(t[rs].sum);
  44. lazya[ls]+=lazya[x];mo(lazya[ls]);
  45. lazya[rs]+=lazya[x];mo(lazya[rs]);
  46. lazya[x]=;
  47. }
  48. }
  49.  
  50. void upc(int x,int l,int r,long long k)
  51. {
  52. if(l>t[x].r||r<t[x].l)return;
  53. if(l<=t[x].l&&t[x].r<=r)
  54. {
  55. t[x].sum*=k;mo(t[x].sum);
  56. lazym[x]*=k;mo(lazym[x]);
  57. lazya[x]*=k;mo(lazya[x]);
  58. return;
  59. }
  60. pushdown(x);
  61. upc(lson(x),l,r,k);
  62. upc(rson(x),l,r,k);
  63. t[x].sum=t[lson(x)].sum+t[rson(x)].sum;mo(t[x].sum);
  64. }
  65. void upj(int x,int l,int r,long long k)
  66. {
  67. if(l>t[x].r||r<t[x].l)return;
  68. if(l<=t[x].l&&t[x].r<=r)
  69. {
  70. t[x].sum+=(t[x].r-t[x].l+)*k;mo(t[x].sum);
  71. lazya[x]+=k;mo(lazya[x]);
  72. return;
  73. }
  74. pushdown(x);
  75. upj(lson(x),l,r,k);
  76. upj(rson(x),l,r,k);
  77. t[x].sum=t[lson(x)].sum+t[rson(x)].sum;mo(t[x].sum);
  78. }
  79. long long query(int x,int l,int r)
  80. {
  81. if(l>t[x].r||r<t[x].l)return ;
  82. if(l<=t[x].l&&t[x].r<=r) return t[x].sum;
  83. pushdown(x);
  84. return (query(lson(x),l,r)%p+query(rson(x),l,r)%p)%p;
  85. }
  86.  
  87. int main()
  88. {
  89. //freopen("test.in","r",stdin);
  90. scanf("%lld%lld",&n,&p);
  91. for(int i=;i<=n;i++)scanf("%lld",a+i);
  92. scanf("%lld",&m);
  93. maketree(,,n);
  94. for(long long i=,mode,x,y,k;i<=m;i++)
  95. {
  96. scanf("%lld",&mode);
  97. if(mode==)
  98. {
  99. scanf("%lld%lld%lld",&x,&y,&k);
  100. upc(,x,y,k);
  101. }
  102. else if(mode==)
  103. {
  104. scanf("%lld%lld%lld",&x,&y,&k);
  105. upj(,x,y,k);
  106. }
  107. else
  108. {
  109. scanf("%lld%lld",&x,&y);
  110. printf("%lld\n",query(,x,y));
  111. }
  112. }
  113. return ;
  114. }

洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列的更多相关文章

  1. 洛谷 P4093: bzoj 4553: [HEOI2016/TJOI2016]序列

    题目传送门:洛谷P4093. 题意简述: 给定一个长度为 \(n\) 的序列 \(a\). 同时这个序列还可能发生变化,每一种变化 \((x_i,y_i)\) 对应着 \(a_{x_i}\) 可能变成 ...

  2. 1798. [AHOI2009]维护序列【线段树】

    Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...

  3. bzoj 1798 Seq 维护序列seq —— 线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1798 这题还4A... 注意:cnt 从1开始:各种模 p:乘法标记初始值是 1:可能乘 0 ...

  4. 洛谷P2023 [AHOI2009]维护序列(线段树区间更新,区间查询)

    洛谷P2023 [AHOI2009]维护序列 区间修改 当我们要修改一个区间时,要保证 \(ax+b\) 的形式,即先乘后加的形式.当将区间乘以一个数 \(k\) 时,原来的区间和为 \(ax+b\) ...

  5. [洛谷P2023] [AHOI2009]维护序列

    洛谷题目链接:[AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列 ...

  6. 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)

    洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...

  7. 洛谷 P2023 [AHOI2009]维护序列

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...

  8. 洛谷 P2023 [AHOI2009]维护序列 题解

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...

  9. 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解

    题目传送: P3373 [模板]线段树 2  P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...

随机推荐

  1. 【POJ 1475】 Pushing Boxes

    [题目链接] http://poj.org/problem?id=1475 [算法] 双重BFS [代码] #include <algorithm> #include <bitset ...

  2. hdu3507Print Article(斜率优化dp)

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  3. html5的Form新特性

    form新增的输入型控件: 名称 说明 图例 email 电子邮箱文本框,显示跟普通的没什么区别 tel  电话号码,pc端不会有明显的变化,但是移动端会自动切换键盘,输入有误不会阻止默认提交   u ...

  4. spring定时任务Cron时间设定

    直接举例: 0 10 0 * *?分别对应的是 秒 分 时 日 月 周 年 秒(0–59)分钟(0–59)小时(0–23)日(1–31)月(1–12或JAN–DEC)周(1–7或SUN–SAT)年(1 ...

  5. 前端HTML中float学习笔记

    float元素原本的作用是用来使文字包裹图片,现在人们更多的是用来进行布局(ps:有没有点滥用的意思) 也就是说本来你排好的界面设计,但是因为浮动会导致元素脱离文档流,使得其他非浮动的块级元素会无视这 ...

  6. 【Hexo】deploy出错的解决方法

    .ERROR Deployer not found: git 执行npm install hexo-deployer-git --save .$ hexo d INFO Deploying: git ...

  7. 极客学院免费VIP

    [手快福利]用我的链接注册极客学院,你我都能免费得30天VIP!6500+编程开发视频教程随便学,还能下载资料和源码 http://e.jikexueyuan.com/invite/index.htm ...

  8. iproute2和tc的高级路由用法

    #Linux advanced router ip link show #显示链路 ip addr show #显示地址(或ifconfig) ip route show #显示路由(route -n ...

  9. C# 获得剪贴板内容和 richTextBox部分文本设置颜色

    try { MemoryStream vMemoryStream = iData.GetData("Html Format") as MemoryStream; if (vMemo ...

  10. linux中tomcat启动脚本:关闭、发布、重启、测试是否成功

    说明 在使用jenkins持续集成时,需要实现自动发布包到tomcat.该脚本实现了在jenkins将包发送到linux服务器上后的自动关闭.发布.启动.测试启动是否成功的过程 思路 该思路以tomc ...