P3373 【模板】线段树 2

题目描述

如题,已知一个数列,你需要进行下面三种操作:

1.将某区间每一个数乘上x

2.将某区间每一个数加上x

3.求出某区间每一个数的和

输入格式

第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

输出格式

输出包含若干行整数,即为所有操作3的结果。

输入输出样例

输入 #1

5 5 38

1 5 4 2 3

2 1 4 1

3 2 5

1 2 4 2

2 3 5 5

3 1 4

输出 #1

17

2

说明/提示

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强_

样例说明:

故输出应为17、2(40 mod 38=2)

【思路】

线段树

大部分的地方是和线段树1这道题一样的

我只在这里说一下不同的地方

【取模】

在每一次有加法或者有乘法

涉及到运算的地方能模的都模一下就好了

【乘法和加法】

原来线段树1模板里面有一个lazy

那是因为有加法这种运算

现在有加法和乘法这两种运算

那就开两个类似lazy的东西储存就好了

【lazy标记的修改】

在修改加法lazy标记的时候就正常修改就好了

但是修改乘法的时候就不行了

因为前面可能有加过的数

所以还要连带着一起修改一下加法的lazy标记

因为入过前面加过某个数

那现在就是

(a + b)

这个时候如果乘上一个数c

(a +b) * c = ac + bc

a乘了c,加法的lazy标记也乘了c所以要修改加法的标记

【完整代码】

  1. #include<iostream>
  2. #include<cstdio>
  3. #define int long long
  4. #define lson (k << 1)
  5. #define rson (k << 1 | 1)
  6. using namespace std;
  7. const int Max = 100005;
  8. int read()
  9. {
  10. int sum = 0,fg = 1;
  11. char c = getchar();
  12. while(c < '0' || c > '9')
  13. {
  14. if(c == '-')fg = -1;
  15. c = getchar();
  16. }
  17. while(c >= '0' && c <= '9')
  18. {
  19. sum = sum * 10 + c - '0';
  20. c = getchar();
  21. }
  22. return sum * fg;
  23. }
  24. int n,m,p;
  25. int opl,opr,opx;
  26. int ans;
  27. struct node
  28. {
  29. int l,r;
  30. int sum;
  31. int cheng,jia;
  32. }a[Max << 2];
  33. void build(int k,int l,int r)
  34. {
  35. a[k].cheng = 1;
  36. a[k].jia = 0;
  37. a[k].l = l,a[k].r = r;
  38. if(l == r)
  39. {
  40. a[k].sum = read();
  41. a[k].sum %= p;
  42. return;
  43. }
  44. int mid = (l + r) >> 1;
  45. build(lson,l,mid);
  46. build(rson,mid + 1,r);
  47. a[k].sum = a[lson].sum + a[rson].sum;
  48. a[k].sum %= p;
  49. }
  50. void down(int k)
  51. {
  52. if(a[k].jia != 0 || a[k].cheng != 1)
  53. {
  54. a[rson].cheng = (a[rson].cheng * a[k].cheng) % p;
  55. a[lson].cheng = (a[lson].cheng * a[k].cheng) % p;
  56. a[rson].jia = (a[rson].jia * a[k].cheng + a[k].jia) % p;
  57. a[lson].jia = (a[lson].jia * a[k].cheng + a[k].jia) % p;
  58. a[rson].sum = (a[rson].sum * a[k].cheng % p + a[k].jia * (a[rson].r - a[rson].l + 1)) % p;
  59. a[lson].sum = (a[lson].sum * a[k].cheng % p + a[k].jia * (a[lson].r - a[lson].l + 1)) % p;
  60. a[k].cheng = 1;
  61. a[k].jia = 0;
  62. }
  63. }
  64. void change1(int k)
  65. {
  66. if(opl <= a[k].l && opr >= a[k].r)
  67. {
  68. a[k].cheng = (a[k].cheng * opx) % p;
  69. a[k].jia = (a[k].jia * opx) % p;
  70. a[k].sum = (a[k].sum * opx) % p;
  71. return;
  72. }
  73. down(k);
  74. int mid = (a[k].l + a[k].r) >> 1;
  75. if(opl <= mid)change1(lson);
  76. if(opr > mid)change1(rson);
  77. a[k].sum = (a[lson].sum + a[rson].sum) % p;
  78. }
  79. void change2(int k)
  80. {
  81. if(opl <= a[k].l && opr >= a[k].r)
  82. {
  83. a[k].jia = (a[k].jia + opx) % p;
  84. a[k].sum = (a[k].sum + (a[k].r - a[k].l + 1) * opx % p) % p;
  85. return;
  86. }
  87. down(k);
  88. int mid = (a[k].l + a[k].r) >> 1;
  89. if(opl <= mid)change2(lson);
  90. if(opr > mid)change2(rson);
  91. a[k].sum = (a[lson].sum + a[rson].sum) % p;
  92. }
  93. void query(int k)
  94. {
  95. if(opl <= a[k].l && opr >= a[k].r)
  96. {
  97. ans += a[k].sum;
  98. ans %= p;
  99. return;
  100. }
  101. down(k);
  102. int mid = (a[k].l + a[k].r) >> 1;
  103. if(opl <= mid)query(lson);
  104. if(opr > mid)query(rson);
  105. }
  106. signed main()
  107. {
  108. n = read(),m = read(),p = read();
  109. build(1,1,n);
  110. for(register int i = 1;i <= m;++ i)
  111. {
  112. int qwq = read();
  113. if(qwq == 1)
  114. {
  115. opl = read(),opr = read(),opx = read();
  116. change1(1);
  117. }
  118. else
  119. if(qwq == 2)
  120. {
  121. opl = read(),opr = read(),opx = read();
  122. change2(1);
  123. }
  124. else
  125. {
  126. opl = read(),opr = read();
  127. ans = 0;
  128. query(1);
  129. cout << ans % p << endl;
  130. }
  131. }
  132. return 0;
  133. }

洛谷 P3373 【模板】线段树 2 题解的更多相关文章

  1. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  2. 线段树_区间加乘(洛谷P3373模板)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字 ...

  3. 洛谷 P2391 白雪皑皑 线段树+优化

    题目描述: 现在有 \(N\) 片雪花排成一列. Pty 要对雪花进行$ M $次染色操作,第 \(i\)次染色操作中,把\((i*p+q)%N+1\) 片雪花和第\((i*q+p)%N+1\)片雪花 ...

  4. 洛谷P5280 [ZJOI2019]线段树

      https://www.luogu.org/problemnew/show/P5280 省选的时候后一半时间开这题,想了接近两个小时的各种假做法,之后想的做法已经接近正解了,但是有一些细节问题理不 ...

  5. 洛谷 - P1198 - 最大数 - 线段树

    https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...

  6. 【洛谷】【线段树】P1471 方差

    [题目背景:] 滚粗了的HansBug在收拾旧数学书,然而他发现了什么奇妙的东西. [题目描述:] 蒟蒻HansBug在一本数学书里面发现了一个神奇的数列,包含N个实数.他想算算这个数列的平均数和方差 ...

  7. 【洛谷】【线段树】P1047 校门外的树

    [题目描述:] 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L ...

  8. 【洛谷】【线段树】P1886 滑动窗口

    [题目描述:] 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. [输入格式:] 输入一共 ...

  9. 【洛谷】【线段树】P3353 在你窗外闪耀的星星

    [题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...

  10. 洛谷P3374(线段树)(询问区间和,支持单点修改)

    洛谷P3374 //询问区间和,支持单点修改 #include <cstdio> using namespace std; ; struct treetype { int l,r,sum; ...

随机推荐

  1. 【JVM学习】3.深入解析强引用、软引用、弱引用、幻象引用

    来源:公众号:猿人谷 关于强引用.软引用.弱引用.幻象引用的区别,在很多公司的面试题中经常出现,可能有些小伙伴觉得这个知识点比较冷门,但其实大家在开发中经常用到,如new一个对象的时候就是强引用的应用 ...

  2. 基础知识---IEnumerable、ICollection、IList、IQueryable

    一.定义 IEnumerable public interface IEnumerable<out T> : IEnumerable ICollection public interfac ...

  3. C++分治策略实现二分搜索

    问题描述: 给定已排好序的n个元素组成的数组,现要利用二分搜索算法判断特定元素x是否在该有序数组中. 细节须知: (1)由于可能需要对分治策略实现二分搜索的算法效率进行评估,故使用大量的随机数对算法进 ...

  4. 【转】西门子PLC以太网 通讯协议 解析

    一直想把三菱和西门子这两个使用频率最高的PLC上位通讯,融合到WCS系统的框架里: 现在三菱主流使用Q系列,使用的是MC协议, 前一段时间也写过一个入门介绍: 三菱Q系列通讯方式设计说明 去年8月份, ...

  5. CocosCreator 2.1.2 Shader组件

    本篇文章相关导读: 新版ShaderHelper,支持 Creator 2.1.2 ! 社区大佬揭开 Creator 2.1.2 材质系统的神秘面纱! 为什么要选择使用TypeScript,看了就知道 ...

  6. C# Newtonsoft.Json.JsonReaderException:“Could not convert string to decimal:

    使用Newtonsoft.Json,报以上错误,问题的原因是有"",把“”替换成null: 以前的json: [{"WengvNj":"df5c38c ...

  7. 解决Hangfire 导致服务器内存飙涨

    最近因为项目需要调度作业服务,之前看张队推荐过一篇https://www.cnblogs.com/yudongdong/p/10942028.html 故直接拿过来实操,发现很好用,简单.方便  执行 ...

  8. 今天是JAVA诞生日

    今天是JAVA诞生日,祝贺!!! 1995年5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器,Java诞生. https://baike.baidu.com/it ...

  9. 攻防世界 高手进阶区 web cat

    php cURL CURLOPT_SAFE_UPLOAD django DEBUG mode Django使用的是gbk编码,超过%F7的编码不在gbk中有意义 当 CURLOPT_SAFE_UPLO ...

  10. Centos7 安装腾达U12驱动无线网卡

    解决过程: 办法一: CentOS7.3 默认的内核版本较低,为 3.10.0-514.el7.x86_64. 无论是使用腾达官方提供的驱动,还是github 上的驱动(链接 https://gith ...