题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828

给你n个数,三种操作。操作1是将l到r之间的数都加上x;操作2是将l到r之间的数都开方;操作3是求出l到r之间的和。

操作1和3就不说了,关键是开方操作。

一个一个开方,复杂度太高,无疑会T。所以我们来剪枝一下。

我们可以观察,这里一个数最多开方4,5次(loglogx次)就会到1,所以要是一段区间最大值为1的话,就不需要递归开方下去了。这是一个剪枝。

如果一段区间的数都是一样大小(最大值等于最小值),那么开方的话,值也会相同。所以只要一次开方就好了,而一次开方也相当于减去 x-sqrt(x)。这是剪枝二。

有了两个剪枝,原本是过了... 后来数据加强了,就T了,无奈...

  1. //#pragma comment(linker, "/STACK:102400000, 102400000")
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <cstdio>
  7. #include <vector>
  8. #include <cmath>
  9. #include <ctime>
  10. #include <list>
  11. #include <set>
  12. #include <map>
  13. using namespace std;
  14. typedef long long LL;
  15. const int N = 1e5 + ;
  16. struct SegTree {
  17. int l, r, mid;
  18. LL sum, lazy, Max, Min;
  19. }T[N << ];
  20.  
  21. void build(int p, int l, int r) {
  22. int ls = p << , rs = (p << )|;
  23. T[p].l = l, T[p].r = r, T[p].mid = (l + r) >> , T[p].lazy = ;
  24. if(l == r) {
  25. scanf("%lld", &T[p].sum);
  26. T[p].Max = T[p].Min = T[p].sum;
  27. return ;
  28. }
  29. build(ls, l, T[p].mid);
  30. build(rs, T[p].mid + , r);
  31. T[p].sum = (T[ls].sum + T[rs].sum);
  32. T[p].Min = min(T[ls].Min, T[rs].Min);
  33. T[p].Max = max(T[ls].Max, T[rs].Max);
  34. }
  35.  
  36. void update_add(int p, int l, int r, LL val) {
  37. int ls = p << , rs = (p << )|;
  38. if(T[p].l == l && T[p].r == r) {
  39. T[p].Min += val;
  40. T[p].Max += val;
  41. T[p].sum += (r - l + ) * val;
  42. T[p].lazy += val;
  43. return ;
  44. }
  45. if(T[p].lazy) {
  46. T[ls].lazy += T[p].lazy, T[rs].lazy += T[p].lazy;
  47. T[ls].sum += (T[ls].r - T[ls].l + )*T[p].lazy;
  48. T[rs].sum += (T[rs].r - T[rs].l + )*T[p].lazy;
  49. T[ls].Max += T[p].lazy, T[ls].Min += T[p].lazy;
  50. T[rs].Max += T[p].lazy, T[rs].Min += T[p].lazy;
  51. T[p].lazy = ;
  52. }
  53. if(r <= T[p].mid) {
  54. update_add(ls, l, r, val);
  55. }
  56. else if(l > T[p].mid) {
  57. update_add(rs, l, r, val);
  58. }
  59. else {
  60. update_add(ls, l, T[p].mid, val);
  61. update_add(rs, T[p].mid + , r, val);
  62. }
  63. T[p].sum = (T[ls].sum + T[rs].sum);
  64. T[p].Min = min(T[ls].Min, T[rs].Min);
  65. T[p].Max = max(T[ls].Max, T[rs].Max);
  66. }
  67.  
  68. void update(int p, int l, int r) {
  69. if(T[p].Max == ) //最大值为1 就不需要开方了
  70. return ;
  71. int ls = p << , rs = (p << )|;
  72. if(T[p].l == l && T[p].r == r && T[p].Max == T[p].Min) {
  73. LL temp = T[p].Max - (LL)sqrt(T[p].Max*1.0);
  74. T[p].Max -= temp;
  75. T[p].Min -= temp;
  76. T[p].lazy -= temp;
  77. T[p].sum -= (r - l + )*temp;
  78. return ;
  79. }
  80. if(T[p].lazy) {
  81. T[ls].lazy += T[p].lazy, T[rs].lazy += T[p].lazy;
  82. T[ls].sum += (T[ls].r - T[ls].l + )*T[p].lazy;
  83. T[rs].sum += (T[rs].r - T[rs].l + )*T[p].lazy;
  84. T[ls].Max += T[p].lazy, T[ls].Min += T[p].lazy;
  85. T[rs].Max += T[p].lazy, T[rs].Min += T[p].lazy;
  86. T[p].lazy = ;
  87. }
  88. if(r <= T[p].mid) {
  89. update(ls, l, r);
  90. }
  91. else if(l > T[p].mid) {
  92. update(rs, l, r);
  93. }
  94. else {
  95. update(ls, l, T[p].mid);
  96. update(rs, T[p].mid + , r);
  97. }
  98. T[p].sum = (T[ls].sum + T[rs].sum);
  99. T[p].Min = min(T[ls].Min, T[rs].Min);
  100. T[p].Max = max(T[ls].Max, T[rs].Max);
  101. }
  102.  
  103. LL query(int p, int l, int r) {
  104. int ls = p << , rs = (p << )|;
  105. if(T[p].l == l && T[p].r == r) {
  106. return T[p].sum;
  107. }
  108. if(T[p].lazy) {
  109. T[ls].lazy += T[p].lazy, T[rs].lazy += T[p].lazy;
  110. T[ls].sum += (T[ls].r - T[ls].l + )*T[p].lazy;
  111. T[rs].sum += (T[rs].r - T[rs].l + )*T[p].lazy;
  112. T[ls].Max += T[p].lazy, T[ls].Min += T[p].lazy;
  113. T[rs].Max += T[p].lazy, T[rs].Min += T[p].lazy;
  114. T[p].lazy = ;
  115. }
  116. if(r <= T[p].mid) {
  117. return query(ls, l, r);
  118. }
  119. else if(l > T[p].mid) {
  120. return query(rs, l, r);
  121. }
  122. else {
  123. return query(ls, l, T[p].mid) + query(rs, T[p].mid + , r);
  124. }
  125. }
  126.  
  127. int main()
  128. {
  129. int n, m, t, c, l, r;
  130. LL val;
  131. scanf("%d", &t);
  132. while(t--) {
  133. scanf("%d %d", &n, &m);
  134. build(, , n);
  135. while(m--) {
  136. scanf("%d %d %d", &c, &l, &r);
  137. if(c == ) {
  138. scanf("%lld", &val);
  139. update_add(, l, r, val);
  140. }
  141. else if(c == ) {
  142. update(, l, r);
  143. }
  144. else {
  145. printf("%lld\n", query(, l, r));
  146. }
  147. }
  148. }
  149. return ;
  150. }

HDU 5828 Rikka with Sequence (线段树+剪枝优化)的更多相关文章

  1. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  2. HDU 5828 Rikka with Sequence(线段树区间加开根求和)

    Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...

  3. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  4. 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence

    // 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...

  5. HDU 5828 Rikka with Sequence (线段树)

    Rikka with Sequence 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  6. HDU 5828 Rikka with Sequence(线段树 开根号)

    Rikka with Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  7. hdu 4893 Wow! Such Sequence!(线段树)

    题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 改动k的为值添加d 2 l r, 查询l到r的区间和 3 l r. 间l到r区间上的所以数变成 ...

  8. HDU 6089 Rikka with Terrorist (线段树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...

  9. HDU 5634 Rikka with Phi 线段树

    题意:bc round 73 div1 D 中文题面 分析:注意到10^7之内的数最多phi O(log(n))次就会变成1, 因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护. 每次求p ...

随机推荐

  1. 如何使用SQL Server链接服务器访问DB2 Server

    首先,需要安装Microsoft OLE DB Provider for DB2 下载地址:http://download.microsoft.com/download/B/B/2/BB22098A- ...

  2. linux添加环境变量

    修改  /当前用户/.bash_profile文件,修改export PATH,添加自己的可执行程序的目录即可 例如: /root/.bash_profile export PATH=$PATH:/u ...

  3. 【解题报告】[动态规划] RQNOJ PID106 / 最大加权矩形

    原题地址:http://www.rqnoj.cn/problem/106 解题思路: 一维的情况下求最大字串和的状态转移方程是:s[i]=max{s[i-1]+a[i],a[i]} 二维的情况下,只要 ...

  4. adb shell 查找并删除文件

    # -*- coding: cp936 -*- ## function: remove file ## remark: python version -- import os,sys import l ...

  5. 使用服务器端控制AJAX页面缓存

    你知道 response.setHeader("Cache-Control","no-cache"); 这条语句是干什么的吗? 这是用来防止浏览器缓存动态内容生 ...

  6. EL表达式(胖先生版)

    EL表达式没有指定范围,从最小范围开始 <% pageContext.setAttribute("shxt", "java web"); request. ...

  7. ASIFormDataRequest 登录

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL: [NSURL URLWithString: @"http: ...

  8. div错位解决IE6、IE7、IE8样式不兼容问题

    IE6里DIV错位的问题       采用”FLOAT:LEFT“的DIV在IE8.IE7.都没问题,IE6下却向下移动,出现空白.这是因为,IE6采用的内核默认把DIV之间的距离增加了3~5个PX, ...

  9. Win7桌面快捷方式全变成某个软件的图标,然后所有快捷方式都只打开这个图标的软件

    电脑真是用到老学老好,之前没有遇到的情况,今天终于碰上了. 由于电脑桌面搜狗浏览器图标总不显示,于是选择快捷方式的打开方式为搜狗浏览器,结果,尼玛呀,全部快捷图标都变成搜狗的. 上网找了一下,双击就搞 ...

  10. 【LeetCode】165 - Compare Version Numbers

    Compare two version numbers version1 and version2.If version1 > version2 return 1, if version1 &l ...