题目链接: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 + 5;
 16 struct SegTree {
 17     int l, r, mid;
 18     LL sum, lazy, Max, Min;
 19 }T[N << 2];
 20
 21 void build(int p, int l, int r) {
 22     int ls = p << 1, rs = (p << 1)|1;
 23     T[p].l = l, T[p].r = r, T[p].mid = (l + r) >> 1, T[p].lazy = 0;
 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 + 1, 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 << 1, rs = (p << 1)|1;
 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 + 1) * 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 + 1)*T[p].lazy;
 48         T[rs].sum += (T[rs].r - T[rs].l + 1)*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 = 0;
 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 + 1, 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) //最大值为1 就不需要开方了
 70         return ;
 71     int ls = p << 1, rs = (p << 1)|1;
 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 + 1)*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 + 1)*T[p].lazy;
 83         T[rs].sum += (T[rs].r - T[rs].l + 1)*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 = 0;
 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 + 1, 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 << 1, rs = (p << 1)|1;
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 + 1)*T[p].lazy;
111         T[rs].sum += (T[rs].r - T[rs].l + 1)*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 = 0;
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 + 1, 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(1, 1, n);
135         while(m--) {
136             scanf("%d %d %d", &c, &l, &r);
137             if(c == 1) {
138                 scanf("%lld", &val);
139                 update_add(1, l, r, val);
140             }
141             else if(c == 2) {
142                 update(1, l, r);
143             }
144             else {
145                 printf("%lld\n", query(1, l, r));
146             }
147         }
148     }
149     return 0;
150 }

View Code

转载于:https://www.cnblogs.com/Recoder/p/5762299.html

HDU 5828 Rikka with Sequence (线段树+剪枝优化)相关推荐

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

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

  2. hdu - 6681 Rikka with Cake 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6681 题意:给定一个左下顶点为,右上顶点为的矩形,然后给你k条射线,每条射线的起点及方向(上下左右)都 ...

  3. HDU 1166 敌兵布阵(线段树:点更新,区间求和)

    HDU 1166 敌兵布阵(线段树:点更新,区间求和) http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意: 给你n个整数,然后给你多条命令,每条命令如 ...

  4. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  5. 2019CCPC网络赛 1002 HDU 6703(权值线段树)

    2019CCPC网络赛 1002 HDU 6703(权值线段树) 思路:用权值线段树存题目给的数据后,2操作就是求权值线段树中大于等于k的部分中,靠近左端点的第一个大于r的值(这个求出来的只是原序列中 ...

  6. HDU 6070 Dirt Ratio(线段树、二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=6070 题解 首先不难看出错误率是单调的,那么我们可以直接二分答案x,某个区间的错误率=区间数的种类cnt/区间长 ...

  7. hdu 5692 Snacks(dfs序+线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5692 解题思路:这道题是树节点的点权更新,而且涉及到子树,常用的思路是利用dfs序,用线段树来对区间进 ...

  8. Minimum Inversion Number HDU - 1394(权值线段树/树状数组)

    The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...

  9. hdu 4391 Paint The Wall 线段树 +优化 2012 Multi-University Training Contest 10 )

    http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意: 刷墙, 以开始 有 n个节点,每个节点有一种颜色 ,m 次询问 m次  输入 a,l,r,z 如果 ...

最新文章

  1. java restful接口开发实例_Spring Boot 中 10 行代码构建 RESTful 风格应用!
  2. 手把手教你搭建 ELK 实时日志分析平台
  3. POJ 2253 Frogger(最短路Floyd)题解
  4. 20本最好的Linux免费书籍
  5. atitit。wondows 右键菜单的管理与位置存储
  6. 22 WM配置-策略-入库策略2-定义未清存储策略C(Open Strategy)
  7. .net操作xml小结 (转)
  8. 深度测试与alpha混合(1)
  9. leetcode 14 最长公共前缀(python)
  10. 在linux中配置编译u-boot方法,U-Boot编译过程解析
  11. 曙光服务器bios开启vt虚拟化,BIOS怎么开启虚拟化技术VT
  12. Skype国际版最新版及老版本下载
  13. mysql中key的用法_数据库中KEY的用法
  14. Golang 逃逸分析
  15. 实现现代汽车SoC功能安全的实践和挑战
  16. 【BlockingQueue】BlockingQueue接口方法说明和区别
  17. java.lang.NoClassDefFoundError异常解决
  18. 2020年 java题库
  19. HBuilderX 最新安装使用教程,附详细图解,持续更新
  20. 02笔记 离散数学——命题逻辑——基于离散数学(第3版)_章炯民,陶增乐

热门文章

  1. 项目经理之项目经理的基本特征
  2. OneAlert 入门(一)——事件流
  3. javascript里的面向对象
  4. 《银河英雄传说》杨威利经典语录1(田中芳树最经典的作品,我顶级拥护!有志同道合的一定要来给我留言!)...
  5. extra energy theory
  6. download first at netease music
  7. 怎么用latex写ppt呢?
  8. 剑桥毕业之后创业的可能的在商学院的出路
  9. X.509 数字证书结构和实例
  10. easyUi创建临时Dialog