(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

题意:传送门

 原题目描述在最下面。

 4种操作,1:区间加法,2:区间乘法,3:区间的所有数都变成一个数,4:访问区间每个数的p次方和(1 <= p <= 3)。

思路:

 三个lazy标记:lazy1表示区间加上的数的延迟,lazy2表示区间乘上的数的延迟,lazy3表示区间变成的那个数字。初始化lazy1 = lazy3 = 0, lazy2 = 1.

如果进行3号操作,则将lazy1和lazy2全部恢复初始值。

 对于1,2号操作,假设原数是x,乘上a,加上b。则 \(a \Rightarrow a \times x + b\) 。

 $$sum1 = \sum x \Rightarrow \sum (a\times x + b) = sum1 \times a + b \times length$$

 $$sum2 = \sum x^2 \Rightarrow \sum (a\times x + b)^2 \Rightarrow \sum (a^2\times x2+b2+2\times a\times b\times x)=sum2\times a2+b2 \times length+2\times a\times b\times sum1

\[&emsp;$$sum3 = \sum x^3 \Rightarrow \sum (a\times x + b)^3 \Rightarrow \sum (a^3\times x^3 + b^3 + 3\times a^2\times x^2\times b+3\times a \times x\times b^2)= sum3 \times a^3 + b^3 \times length + 3\times sum2\times a^2 \times b+ 3\times sum1\times a\times b^2
\]

 注意了,再进行更新sum操作时,要先更新sum3再更新sum2最后更新sum1。比如sum3式子中的sum2的含义是原始数列的sum2,不是更新后的sum2。

 然后就是对于push_down中的lazy1和lazy2的处理。

 \(lazy1 \Rightarrow lazy1\times a + b\)

 $lazy2 \Rightarrow lazy2\times a $

(因为update哪里忘了写return;,导致debug一天)

AC代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <vector>
  7. #include <queue>
  8. #include <algorithm>
  9. #include <set>
  10. #include<assert.h>
  11. #define lson rt<<1
  12. #define rson rt<<1|1
  13. #define lowbit(x) (x)&(-(x))
  14. using namespace std;
  15. typedef long long LL;
  16. const int INF = 0x3f3f3f3f;
  17. const int N = (int)1e5+7;
  18. const int mod = 10007;
  19. int n, q;
  20. int ar[N];
  21. struct lp{
  22. int l,r;
  23. LL sum1,sum2,sum3,d;
  24. LL lazy1,lazy2,lazy3;
  25. }cw[N<<2];
  26. //pushdown先乘除后加减
  27. //加法 lazy1 lazy2 乘法
  28. void push_up(int rt){
  29. cw[rt].sum1 = (cw[lson].sum1+cw[rson].sum1)%mod;
  30. cw[rt].sum2 = (cw[lson].sum2+cw[rson].sum2)%mod;
  31. cw[rt].sum3 = (cw[lson].sum3+cw[rson].sum3)%mod;
  32. }
  33. void build(int l,int r,int rt){
  34. int m=(l+r)>>1;
  35. cw[rt].l=l;cw[rt].r=r;
  36. cw[rt].d=r-l+1;
  37. cw[rt].sum1 = cw[rt].sum2 = cw[rt].sum3=0;
  38. cw[rt].lazy1 = cw[rt].lazy3 = 0;
  39. cw[rt].lazy2 = 1;
  40. if(l==r){return;}
  41. build(l,m,lson); build(m+1,r,rson);
  42. push_up(rt);
  43. }
  44. //pushdown先乘除后加减
  45. void push_down(int rt){
  46. if(cw[rt].lazy3){
  47. LL tmp = cw[rt].lazy3*cw[rt].lazy3%mod*cw[rt].lazy3%mod;
  48. cw[lson].lazy1=cw[rson].lazy1=0;
  49. cw[lson].lazy2=cw[rson].lazy2=1;
  50. cw[lson].lazy3=cw[rson].lazy3=cw[rt].lazy3;
  51. cw[lson].sum3 = cw[lson].d*tmp%mod;
  52. cw[rson].sum3 = cw[rson].d*tmp%mod;
  53. cw[lson].sum2 = cw[lson].d*cw[rt].lazy3%mod*cw[rt].lazy3%mod;
  54. cw[rson].sum2 = cw[rson].d*cw[rt].lazy3%mod*cw[rt].lazy3%mod;
  55. cw[lson].sum1 = cw[lson].d*cw[rt].lazy3%mod;
  56. cw[rson].sum1 = cw[rson].d*cw[rt].lazy3%mod;
  57. cw[rt].lazy3 = 0;
  58. }
  59. if(cw[rt].lazy1!=0||cw[rt].lazy2!=1){
  60. LL add = cw[rt].lazy1, mul = cw[rt].lazy2;
  61. LL l1=cw[lson].sum1,l2=cw[lson].sum2,l3=cw[lson].sum3;
  62. LL r1=cw[rson].sum1,r2=cw[rson].sum2,r3=cw[rson].sum3;
  63. LL tmp = mul*mul%mod*mul%mod;
  64. cw[lson].lazy1=(cw[lson].lazy1*mul%mod+add)%mod;
  65. cw[rson].lazy1=(cw[rson].lazy1*mul%mod+add)%mod;
  66. cw[lson].lazy2=cw[lson].lazy2*mul%mod;
  67. cw[rson].lazy2=cw[rson].lazy2*mul%mod;
  68. cw[lson].sum3=(cw[lson].sum3*tmp%mod + add*add%mod*add%mod*cw[lson].d%mod + 3*cw[lson].sum2*mul%mod*mul%mod*add%mod + 3*cw[lson].sum1*mul%mod*add%mod*add%mod)%mod;
  69. cw[rson].sum3=(cw[rson].sum3*tmp%mod + add*add%mod*add%mod*cw[rson].d%mod + 3*cw[rson].sum2*mul%mod*mul%mod*add%mod + 3*cw[rson].sum1*mul%mod*add%mod*add%mod)%mod;
  70. cw[lson].sum2=(cw[lson].sum2*mul%mod*mul%mod + add*add%mod*cw[lson].d%mod + 2*mul*add*cw[lson].sum1)%mod;
  71. cw[rson].sum2=(cw[rson].sum2*mul%mod*mul%mod + add*add%mod*cw[rson].d%mod + 2*mul*add*cw[rson].sum1)%mod;
  72. cw[lson].sum1=(cw[lson].sum1*mul+add*cw[lson].d)%mod;
  73. cw[rson].sum1=(cw[rson].sum1*mul+add*cw[rson].d)%mod;
  74. cw[rt].lazy1 = 0;cw[rt].lazy2 = 1;
  75. }
  76. }
  77. //op==1 加法, op==2 乘法, op==3 改变值
  78. void update(int L,int R,int op,int z,int rt){
  79. int l=cw[rt].l, r=cw[rt].r, mid=(l+r)>>1;
  80. if(cw[rt].l>R||cw[rt].r<L)return;
  81. if(L<=l&&r<=R){
  82. LL l1 = cw[rt].sum1, l2 = cw[rt].sum2;
  83. if(op==1){//加法
  84. cw[rt].lazy1 = (z + cw[rt].lazy1)%mod;
  85. cw[rt].sum3 = (cw[rt].sum3 + (z*z%mod)*z%mod*cw[rt].d%mod + 3*z*(cw[rt].sum2+(cw[rt].sum1*z)%mod)%mod)%mod;
  86. cw[rt].sum2 = (cw[rt].sum2 + cw[rt].d*z%mod*z%mod + 2*z*cw[rt].sum1%mod)%mod;
  87. cw[rt].sum1 = (cw[rt].sum1 + cw[rt].d*z%mod)%mod;
  88. }else if(op==2){//乘法
  89. cw[rt].lazy1 = cw[rt].lazy1*z%mod;
  90. cw[rt].lazy2 = cw[rt].lazy2*z%mod;
  91. cw[rt].sum1 = cw[rt].sum1*z%mod;
  92. cw[rt].sum2 = (cw[rt].sum2*z%mod)*z%mod;
  93. cw[rt].sum3 = ((cw[rt].sum3*z%mod)*z%mod)*z%mod;
  94. }else{
  95. cw[rt].lazy1=0;cw[rt].lazy2=1;
  96. cw[rt].lazy3=z;
  97. cw[rt].sum3 = cw[rt].d*z%mod*z%mod*z%mod;
  98. cw[rt].sum2 = cw[rt].d*z%mod*z%mod;
  99. cw[rt].sum1 = cw[rt].d*z%mod;
  100. }
  101. return;
  102. }
  103. if(cw[rt].l==cw[rt].r)return;
  104. push_down(rt);
  105. if(L>mid)update(L,R,op,z,rson);
  106. else if(R<=mid)update(L,R,op,z,lson);
  107. else{
  108. update(L,mid,op,z,lson);
  109. update(mid+1,R,op,z,rson);
  110. }
  111. push_up(rt);
  112. }
  113. LL query(int L,int R,int op,int rt){
  114. int l=cw[rt].l, r=cw[rt].r, mid=(l+r)>>1;
  115. if(L<=l&&r<=R){
  116. if(op==1)return cw[rt].sum1;
  117. else if(op==2)return cw[rt].sum2;
  118. return cw[rt].sum3;
  119. }
  120. if(cw[rt].l==cw[rt].r)return 0;
  121. push_down(rt);
  122. LL sum = 0;
  123. if(L>mid) sum = query(L,R,op,rson);
  124. else if(R<=mid) sum = query(L,R,op,lson);
  125. else {
  126. sum = query(L,mid,op,lson);
  127. sum += query(mid+1,R,op,rson);
  128. }
  129. return (sum%mod);
  130. }
  131. int main(){
  132. while(~scanf("%d%d", &n,&q)&&(n+q)){
  133. build(1,n,1);
  134. while(q--){
  135. int op,l,r,z;
  136. scanf("%d%d%d%d",&op,&l,&r,&z);
  137. if(op<=3){
  138. z%=mod;
  139. update(l,r,op,z,1);
  140. }else{
  141. printf("%lld\n", query(l,r,z,1));
  142. }
  143. }
  144. }
  145. return 0;
  146. }

####原题目描述:
Problem Description
Yuanfang is puzzled with the question below:
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation akInput

There are no more than 10 test cases.

For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.

Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)

The input ends with 0 0.

Output

For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.

Sample Input

5 5

3 3 5 7

1 2 4 4

4 1 5 2

2 2 5 8

4 3 5 3

0 0

Sample Output

307

7489

Source

2013ACM-ICPC杭州赛区全国邀请赛

HDU4578-代码一点都不长的线段树的更多相关文章

  1. HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)

    原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解    By 岩之痕 目录: 一:综述 ...

  3. Mango DS Training #48 ---线段树2 解题手记

    Training address: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38966#overview A.Count Color ...

  4. 线段树 Interval Tree

    一.线段树 线段树既是线段也是树,并且是一棵二叉树,每个结点是一条线段,每条线段的左右儿子线段分别是该线段的左半和右半区间,递归定义之后就是一棵线段树. 例题:给定N条线段,{[2, 5], [4, ...

  5. HDU 1166 敌兵布阵(线段树 单点更新)

     点我看题目  题意 :HDU的中文题也不常见....这道题我就不详述了..... 思路 :这个题用线段树用树状数组都可以,用线段树的时候要注意输入那个地方,输入一个字符串的时候不要紧接着输入两个数字 ...

  6. bzoj 1513 [POI2006]Tet-Tetris 3D(二维线段树)

    1513: [POI2006]Tet-Tetris 3D Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 540  Solved: 175[Submit ...

  7. [SinGuLaRiTy] ZKW线段树

    [SinGuLaRiTy-1007] Copyrights (c) SinGuLaRiTy 2017. All Rights Reserved. 关于ZKW线段树 Zkw线段树是清华大学张昆玮发明非递 ...

  8. [poj3468]A Simple Problem with Integers_线段树

    A Simple Problem with Integers 题目大意:给出n个数,区间加.查询区间和. 注释:1<=n,q<=100,000.(q为操作次数). 想法:嗯...学了这么长 ...

  9. BZOJ3196二逼平衡树——线段树套平衡树(treap)

    此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...

随机推荐

  1. 张嘴高并发,闭口微服务,Docker不了解一下?

    Docker镜像与容器 理解虚拟化 计算机中,虚拟化是一种资源管理技术,打破计算机的内存.网络.硬盘等资源的不可切割的障碍,更好的进行的资源分配: 在实际生产环境中,虚拟化技术主要解决的是高性能的物理 ...

  2. js手机滚屏效果

    原文地址:https://github.com/yanhaijing/zepto.fullpage 第一步:基于移动端的浏览体验,在头部添加浏览器渲染的分辨率 <meta name=" ...

  3. apue 第18章 终端I/O

    终端I/O有两种不同的工作模式: (1)规范模式:输入以行单位进行处理,每个读请求也最多返回一行. (2)非规范模式:输入字符不装配成行. 终端设备是由通常位于内核中的终端驱动程序控制的.每个终端设备 ...

  4. composer安装后台模板

    先下载composer的windows安装包 cmd切换到源代码所在目录 https://www.cnblogs.com/wgphp/p/8001434.html 安装过程可以参照这篇文章 一点问题是 ...

  5. Shell基础(五):sed基本用法、使用sed修改系统配置、sed多行文本处理、sed综合脚本应用

    一.sed基本用法 目标: 本案例要求熟悉sed命令的p.d.s等常见操作,并结合正则表达式,完成以下任务: 1> 删除文件中每行的第二个.最后一个字符    2> 将文件中每行的第一个. ...

  6. nginx,php-fpm性能优化

    When you running a highload website with PHP-FPM via FastCGI, the following tips may be useful to yo ...

  7. WebBug靶场基础篇 — 03

    基础篇 6 - 16 关... 在记录之前,先说一件事 = =! 小学生真多 = =!好心提供一个靶场,玩玩就算了,他挂黑页 ?现在好了,以后这个靶场不对外啊!你高兴了?爽了吧? 都是新手过来的,好心 ...

  8. 前台处理ajax:axios

    """ 1.安装axios cnpm install axios --save 2.src/main.js配置 // 允许ajax发送请求时附带cookie axios. ...

  9. UVA 10522 Height to Area(知三角形三高求面积)

    思路:海伦公式, AC代码: #include<bits/stdc++.h> using namespace std; int main() { int n; scanf("%d ...

  10. JOGL图形形状

    图形对象 要访问程序特定于硬件和操作系统平台,以及其他语言编写,比如C和C++(原生应用)库,Java使用一种称为Java本地接口(JNI)编程框架的工作. JOGL内部使用此接口,如图中下面的图表来 ...