Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 49    Accepted Submission(s): 16

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 ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him. 
 
Input
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
 

很裸的线段树的题目。

但是做起来比较麻烦。

我用sum1,sum2,sum3分别代表和、平方和、立方和。

懒惰标记使用三个变量:

lazy1:是加的数

lazy2:是乘的倍数

lazy3:是赋值为一个常数,为0表示没有。

更新操作需要注意很多细节。

  1. /* **********************************************
  2. Author : kuangbin
  3. Created Time: 2013/8/10 13:24:03
  4. File Name : F:\2013ACM练习\比赛练习\2013杭州邀请赛重现\1003.cpp
  5. *********************************************** */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <iostream>
  10. #include <algorithm>
  11. #include <vector>
  12. #include <queue>
  13. #include <set>
  14. #include <map>
  15. #include <string>
  16. #include <math.h>
  17. #include <stdlib.h>
  18. using namespace std;
  19. const int MOD = ;
  20. const int MAXN = ;
  21. struct Node
  22. {
  23. int l,r;
  24. int sum1,sum2,sum3;
  25. int lazy1,lazy2,lazy3;
  26. }segTree[MAXN*];
  27. void build(int i,int l,int r)
  28. {
  29. segTree[i].l = l;
  30. segTree[i].r = r;
  31. segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = ;
  32. segTree[i].lazy1 = segTree[i].lazy3 = ;
  33. segTree[i].lazy2 = ;
  34. int mid = (l+r)/;
  35. if(l == r)return;
  36. build(i<<,l,mid);
  37. build((i<<)|,mid+,r);
  38. }
  39. void push_up(int i)
  40. {
  41. if(segTree[i].l == segTree[i].r)
  42. return;
  43. segTree[i].sum1 = (segTree[i<<].sum1 + segTree[(i<<)|].sum1)%MOD;
  44. segTree[i].sum2 = (segTree[i<<].sum2 + segTree[(i<<)|].sum2)%MOD;
  45. segTree[i].sum3 = (segTree[i<<].sum3 + segTree[(i<<)|].sum3)%MOD;
  46.  
  47. }
  48.  
  49. void push_down(int i)
  50. {
  51. if(segTree[i].l == segTree[i].r) return;
  52. if(segTree[i].lazy3 != )
  53. {
  54. segTree[i<<].lazy3 = segTree[(i<<)|].lazy3 = segTree[i].lazy3;
  55. segTree[i<<].lazy1 = segTree[(i<<)|].lazy1 = ;
  56. segTree[i<<].lazy2 = segTree[(i<<)|].lazy2 = ;
  57. segTree[i<<].sum1 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD;
  58. segTree[i<<].sum2 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
  59. segTree[i<<].sum3 = (segTree[i<<].r - segTree[i<<].l + )*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD*segTree[i<<].lazy3%MOD;
  60. segTree[(i<<)|].sum1 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD;
  61. segTree[(i<<)|].sum2 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
  62. segTree[(i<<)|].sum3 = (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD*segTree[(i<<)|].lazy3%MOD;
  63. segTree[i].lazy3 = ;
  64. }
  65. if(segTree[i].lazy1 != || segTree[i].lazy2 != )
  66. {
  67. segTree[i<<].lazy1 = ( segTree[i].lazy2*segTree[i<<].lazy1%MOD + segTree[i].lazy1 )%MOD;
  68. segTree[i<<].lazy2 = segTree[i<<].lazy2*segTree[i].lazy2%MOD;
  69. int sum1,sum2,sum3;
  70. sum1 = (segTree[i<<].sum1*segTree[i].lazy2%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD)%MOD;
  71. sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<].sum1%MOD + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
  72. sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<].sum3 % MOD;
  73. sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum2) % MOD;
  74. sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<].sum1) % MOD;
  75. sum3 = (sum3 + (segTree[i<<].r - segTree[i<<].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
  76. segTree[i<<].sum1 = sum1;
  77. segTree[i<<].sum2 = sum2;
  78. segTree[i<<].sum3 = sum3;
  79. segTree[(i<<)|].lazy1 = ( segTree[i].lazy2*segTree[(i<<)|].lazy1%MOD + segTree[i].lazy1 )%MOD;
  80. segTree[(i<<)|].lazy2 = segTree[(i<<)|].lazy2 * segTree[i].lazy2 % MOD;
  81. sum1 = (segTree[(i<<)|].sum1*segTree[i].lazy2%MOD + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD)%MOD;
  82. sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[(i<<)|].sum2 % MOD + *segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[(i<<)|].sum1%MOD + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
  83. sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[(i<<)|].sum3 % MOD;
  84. sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<)|].sum2) % MOD;
  85. sum3 = (sum3 + *segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<)|].sum1) % MOD;
  86. sum3 = (sum3 + (segTree[(i<<)|].r - segTree[(i<<)|].l + )*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
  87. segTree[(i<<)|].sum1 = sum1;
  88. segTree[(i<<)|].sum2 = sum2;
  89. segTree[(i<<)|].sum3 = sum3;
  90. segTree[i].lazy1 = ;
  91. segTree[i].lazy2 = ;
  92.  
  93. }
  94. }
  95. void update(int i,int l,int r,int type,int c)
  96. {
  97. if(segTree[i].l == l && segTree[i].r == r)
  98. {
  99. c %= MOD;
  100. if(type == )
  101. {
  102. segTree[i].lazy1 += c;
  103. segTree[i].lazy1 %= MOD;
  104. segTree[i].sum3 = (segTree[i].sum3 + *segTree[i].sum2%MOD*c%MOD + *segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD*c%MOD)%MOD;
  105. segTree[i].sum2 = (segTree[i].sum2 + *segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + )*c%MOD*c%MOD)%MOD;
  106. segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + )*c%MOD)%MOD;
  107. }
  108. else if(type == )
  109. {
  110. segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
  111. segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
  112. segTree[i].sum1 = segTree[i].sum1*c%MOD;
  113. segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
  114. segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
  115. }
  116. else
  117. {
  118. segTree[i].lazy1 = ;
  119. segTree[i].lazy2 = ;
  120. segTree[i].lazy3 = c%MOD;
  121. segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + )%MOD;
  122. segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD;
  123. segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + )%MOD*c%MOD*c%MOD;
  124. }
  125. return;
  126. }
  127. push_down(i);
  128. int mid = (segTree[i].l + segTree[i].r)/;
  129. if(r <= mid)update(i<<,l,r,type,c);
  130. else if(l > mid)update((i<<)|,l,r,type,c);
  131. else
  132. {
  133. update(i<<,l,mid,type,c);
  134. update((i<<)|,mid+,r,type,c);
  135. }
  136. push_up(i);
  137. }
  138. int query(int i,int l,int r,int p)
  139. {
  140. if(segTree[i].l == l && segTree[i].r == r)
  141. {
  142. if(p == )return segTree[i].sum1;
  143. else if(p== )return segTree[i].sum2;
  144. else return segTree[i].sum3;
  145. }
  146. push_down(i);
  147. int mid = (segTree[i].l + segTree[i].r )/;
  148. if(r <= mid)return query(i<<,l,r,p);
  149. else if(l > mid)return query((i<<)|,l,r,p);
  150. else return (query(i<<,l,mid,p)+query((i<<)|,mid+,r,p))%MOD;
  151. }
  152.  
  153. int main()
  154. {
  155. //freopen("in.txt","r",stdin);
  156. //freopen("out.txt","w",stdout);
  157. int n,m;
  158. while(scanf("%d%d",&n,&m) == )
  159. {
  160. if(n == && m == )break;
  161. build(,,n);
  162. int type,x,y,c;
  163. while(m--)
  164. {
  165. scanf("%d%d%d%d",&type,&x,&y,&c);
  166. if(type == )printf("%d\n",query(,x,y,c));
  167. else update(,x,y,type,c);
  168. }
  169. }
  170. return ;
  171. }

HDU 4578 Transformation (线段树)的更多相关文章

  1. HDU 4578 Transformation --线段树,好题

    题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...

  2. hdu 4578 Transformation 线段树

    没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...

  3. hdu 4578 Transformation 线段树多种操作裸题

    自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...

  4. Transformation HDU - 4578(线段树——懒惰标记的妙用)

    Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  8. HDU 4578 - Transformation - [加强版线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...

  9. HDU 4578——Transformation——————【线段树区间操作、确定操作顺序】

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

随机推荐

  1. c语言简单实现telnet客户端

    c语言简单实现telnet客户端 http://blog.csdn.net/haiwenchen/article/details/69944118

  2. 快速排序算法的c++实现

    很早以前看过快排算法觉得自己掌握了,,课今天用的时候发现老出错,认真想想发现自己一直搞错了... 下面先说一下我的想法: 首先,快排的思想就是 从数列中挑出一个元素,称为 "基准" ...

  3. [New learn]讲解Objective-c的block知识-实践

    1.简介 在之前的文章[New learn]讲解Objective-c的block知识中介绍了block的相关知识.本章中我们将以一个实际例子来简单介绍一下block如何代替代理. 2.原有通过代理实 ...

  4. c语言实现CRC校验和

    最近在摄像头采集的数据清晰度上需要加强,则在每一帧传输的数据包后边加了CRC校验和.CRC校验和有16位的,也有32位的.至于CRC校验和算法原理,我是在百度上学习的,其实网上有很多这种资料.简单的说 ...

  5. [PAT] 1021 Deepest Root (25)(25 分)

    1021 Deepest Root (25)(25 分)A graph which is connected and acyclic can be considered a tree. The hei ...

  6. Python 邮件发送消息

    # 代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:supery import smtplib from email.mime.tex ...

  7. python类的使用与多文件组织

    多文件的组织 跨目录级导入模块 from ..xxfile import xxmodule #从上级目录中的xxfile中导入xxmodule import xxsub_dir.xxfile #从xx ...

  8. 洛谷P3038 牧草种植 [树链剖分]

    题目传送门 牧草种植 题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirec ...

  9. 主元素 II

    主元素 II 给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一. 样例 给出数组[1,2,1,2,1,3,3] 返回 1 注意 数组中只有唯一的主元素 挑战 要求时间复 ...

  10. Eclipse有助于提高开发速度的快捷键

    用Eclipse已经很长一段时间了,自己常用的几个快捷键也已经很熟,但还是有一些自己不经常在开发中使用,但非常使用的快捷键,记录下来,以后利用来提高开发效率. 1.ctrl + shift + r   ...