大意:一个数组,三个操作,第一种是区间[a,b]每个数乘乘,第二种是区间[a,b]每个数加c,第三种是查询[a,b]区间的和并对p取摸。

两种操作就不能简单的只往下传标记。每次传乘法标记时,要把加法标记同时乘上乘法标记,例如某个区间先进来一个加法标记add,之后又进来一个乘法标记mul。

那么结果为(x+add)*mul=x*mul+add*mul。这样向下传标记的时候就相对独立。递归边界更新加法标记之前先乘上该节点的mul,左右儿子down的时候先将儿子的add乘上本节点的mul。

最后说一下sum,比如本节点的存在加法标记x和乘法标记y,并且是先加上x,再乘上y,则左儿子的sum要更新为(sum+x)*y。由于乘法标记传到本节点的时候更新了加法标记,x =x*y,所以sum[o<<1]=(左区间的长度*x)+sum[o<<1]*y。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<cmath>
  7. using namespace std;
  8.  
  9. typedef long long LL;
  10.  
  11. #define N 100010
  12.  
  13. int n,m;
  14. int askd,al,ar,ask;
  15. LL p;
  16.  
  17. LL add[N<<],sum[N<<],mul[N<<];
  18.  
  19. void pushup(int now)
  20. {
  21. sum[now]=(sum[now<<]+sum[now<<|])%p;
  22. }
  23.  
  24. void pushdown(int now,int d)
  25. {
  26. if (add[now]!= || mul[now]!=)
  27. {
  28. mul[now<<]=mul[now<<]*mul[now]%p;
  29. mul[now<<|]=mul[now<<|]*mul[now]%p;
  30. add[now<<]=(add[now]+add[now<<]*mul[now])%p;
  31. add[now<<|]=(add[now]+add[now<<|]*mul[now])%p;
  32. sum[now<<]=(add[now]*(d-(d>>))+sum[now<<]*mul[now])%p;
  33. sum[now<<|]=(add[now]*(d>>)+sum[now<<|]*mul[now])%p;
  34. add[now]=;
  35. mul[now]=;
  36. }
  37. }
  38.  
  39. void build(int nowl,int nowr,int now)
  40. {
  41. sum[now]=;
  42. mul[now]=;
  43. if (nowl==nowr)
  44. {
  45. scanf("%lld",&sum[now]);
  46. return ;
  47. }
  48. int mid=(nowl+nowr)>>;
  49. build(nowl,mid,now<<);
  50. build(mid+,nowr,now<<|);
  51. pushup(now);
  52. }
  53.  
  54. void updata_mul(int nowl,int nowr,int now,int l,int r,int c)
  55. {
  56. if (nowl>=l && nowr<=r)
  57. {
  58. add[now]=add[now]*c%p;
  59. sum[now]=sum[now]*c%p;
  60. mul[now]=mul[now]*c%p;
  61. return ;
  62. }
  63. pushdown(now,nowr-nowl+);
  64. int mid=(nowl+nowr)>>;
  65. if (l<=mid)
  66. updata_mul(nowl,mid,now<<,l,r,c);
  67. if (r>mid)
  68. updata_mul(mid+,nowr,now<<|,l,r,c);
  69. pushup(now);
  70. }
  71.  
  72. void updata_add(int nowl,int nowr,int now,int l,int r,int c)
  73. {
  74. if (nowl>=l && nowr<=r)
  75. {
  76. add[now]=(add[now]+c)%p;
  77. sum[now]=(sum[now]+c*(nowr-nowl+))%p;
  78. return ;
  79. }
  80. pushdown(now,nowr-nowl+);
  81. int mid=(nowl+nowr)>>;
  82. if (l<=mid)
  83. updata_add(nowl,mid,now<<,l,r,c);
  84. if (r>mid)
  85. updata_add(mid+,nowr,now<<|,l,r,c);
  86. pushup(now);
  87. }
  88.  
  89. LL query(int nowl,int nowr,int now,int l,int r)
  90. {
  91. LL res();
  92. if (nowl>=l && nowr<=r)
  93. return sum[now];
  94. pushdown(now,nowr-nowl+);
  95. int mid=(nowl+nowr)>>;
  96. if (l<=mid)
  97. res=(res+query(nowl,mid,now<<,l,r))%p;
  98. if (r>mid)
  99. res=(res+query(mid+,nowr,now<<|,l,r))%p;
  100. return res;
  101. }
  102.  
  103. int main()
  104. {
  105. scanf("%d%lld",&n,&p);
  106. build(,n,);
  107. scanf("%d",&m);
  108. while (m--)
  109. {
  110. scanf("%d",&askd);
  111. if (askd==)
  112. {
  113. scanf("%d%d%d",&al,&ar,&ask);
  114. updata_mul(,n,,al,ar,ask);
  115. }
  116. if (askd==)
  117. {
  118. scanf("%d%d%d",&al,&ar,&ask);
  119. updata_add(,n,,al,ar,ask);
  120. }
  121. if (askd==)
  122. {
  123. scanf("%d%d",&al,&ar);
  124. printf("%lld\n",query(,n,,al,ar));
  125. }
  126. }
  127. return ;
  128. }

【bzoj1798】[Ahoi2009]Seq 维护序列seq的更多相关文章

  1. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  2. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  3. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  4. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  5. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  6. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  7. BZOJ1798[Ahoi2009]Seq 维护序列seq 题解

    题目大意: 有长为N的数列,有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值. ...

  8. 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树

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

  9. 【分块】bzoj1798 [Ahoi2009]Seq 维护序列seq

    分块,打标记,维护两个标记:乘的 和 加的. 每次 区间乘的时候,对 乘标记 和 加标记 都 乘上那个值. 每次 区间加的时候 对 加标记 加上那个值. (ax+b)*v=axv+bv.开 long ...

  10. [bzoj1798][Ahoi2009]Seq 维护序列seq ([洛谷P3373]【模板】线段树 2)

    题目大意:有$n$个数,有$m$个操作,有三种: $1\;l\;r\;x:$把区间$[l,r]$内的数乘上$x$ $2\;l\;r\;x:$把区间$[l,r]$内的数加上$x$ $3\;l\;r:$询 ...

随机推荐

  1. ORACLE中DBMS_SQL的用法

    ORACLE中DBMS_SQL的用法   对于一般的select操作,如果使用动态的sql语句则需要进行以下几个步骤: open   cursor---> parse---> define ...

  2. 初识Typescript及vscode环境配置

    什么是typescript?为什么要用它? typescript简称ts,是js语法的一个超级,由微软团队维护的 js特点(不足) 弱类型:js中的数据变量没有确定的类型,可以存储对象,可以存储数字, ...

  3. BZOJ2007 NOI2010 海拔 平面图转对偶图 最小割

    题面太长啦,请诸位自行品尝—>海拔 分析: 这是我见过算法比较明显的最小割题目了,很明显对于某一条简单路径,海拔只会有一次变换. 而且我们要最终使变换海拔的边权值和最小. 我们发现变换海拔相当于 ...

  4. 排序算法,以php为代码示例

    一.冒泡排序 <?php/** * Created by PhpStorm. * User: 郑楚周 * Date: 2018/9/28 * Time: 16:10 */ /**冒泡排序 * C ...

  5. win7 x64安装glpk

    下载glpk,下载地址:http://ftp.gnu.org/gnu/glpk/

  6. 22Spring基于配置文件的方式配置AOP

    直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(in ...

  7. C语言的移位操作符及位运算

    C语言的移位操作符 位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算.位移位运算符分为左移和右移两种,均为双目运算符.第一运算对象是移位对象,第二个运算对象是所移的二进制位数. 位 ...

  8. POJ 2096 找bug 期望dp

    题目大意: 一个人受雇于某公司要找出某个软件的bugs和subcomponents,这个软件一共有n个bugs和s个subcomponents,每次他都能同时随机发现1个bug和1个subcompon ...

  9. noip模拟赛 残

    分析:这道题有点丧病啊......斐波那契数列本来增长就快,n <= 10^100又套2层,看到题目就让人绝望.不过这种题目还是有套路的.首先求斐波那契数列肯定要用到矩阵快速幂,外层的f可以通过 ...

  10. 洛谷P1710地铁涨价

    题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...