J - Super Mario HDU - 4417

这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好。

不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该可以写的,但是没有写出来。

因为我们要查找一个区间小于等于c的数有多少个,这种区间处理可以用线段树很好的解决,

但是怎么解决呢,我习惯性的直接建树,然后再想怎么做,其实这样不对,

线段树对于我们来说是一个解决问题的工具,不要本末倒置了。

我们想查找一个区间小于等于c的数的个数,用线段树查询很简单,但是怎么建树才可以

让我们每次查询都得到想要的结果呢,这个肯定是不能直接把这个墙的高度直接建树的,应该要先处理一下。

我们可以把查询的高度按升序排序,这样线段树之前更新过的值就不会影响后面的值了。

但是线段树怎么更新呢,这个也可以按升序对墙排个序,这样就解决问题了。

这个思路其实没有特别难想。。。

代码很好敲,但是要注意不要漏掉了,也许都已经更新完了,但是这个答案没有在for循环里面找到。

这个要注意!!!

然后这个题目还可以用主席树写

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <queue>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <iostream>
  8. #define inf 0x3f3f3f3f
  9. #define inf64 0x3f3f3f3f3f3f3f3f
  10. using namespace std;
  11. typedef long long ll;
  12. const int maxn = 2e5+;
  13. ll sum[maxn*], ans[maxn];
  14. int n, m;
  15. struct node
  16. {
  17. ll num, id;
  18. }a[maxn];
  19. struct edge
  20. {
  21. ll l, r, h, id;
  22. edge(ll l=,ll r=,ll h=,ll id=):l(l),r(r),h(h),id(id){}
  23. }ex[maxn];
  24.  
  25. bool cmp(node a,node b)
  26. {
  27. return a.num < b.num;
  28. }
  29.  
  30. bool cmp1(edge a,edge b)
  31. {
  32. return a.h < b.h;
  33. }
  34.  
  35. void update(int id,int l,int r,int pos)
  36. {
  37. if(l==r)
  38. {
  39. sum[id] = ;
  40. return;
  41. }
  42. int mid = (l + r) >> ;
  43. if (pos <= mid) update(id << , l, mid, pos);
  44. else update(id << | , mid + , r, pos);
  45. sum[id] = sum[id << ] + sum[id << | ];
  46. //printf("sum[%d]=%d\n", id, sum[id]);
  47. }
  48.  
  49. ll query(int id,int l,int r,int x,int y)
  50. {
  51. if (x <= l && y >= r) return sum[id];
  52. int mid = (l + r) >> ;
  53. int ans = ;
  54. if (x <= mid) ans += query(id << , l, mid, x, y);
  55. if (y > mid) ans += query(id << | , mid + , r, x, y);
  56. return ans;
  57. }
  58.  
  59. int main()
  60. {
  61. int t;
  62. scanf("%d", &t);
  63. for(int cas=;cas<=t;cas++)
  64. {
  65. memset(ans, , sizeof(ans));
  66. memset(sum, , sizeof(sum));
  67. scanf("%d%d", &n, &m);
  68. for (int i = ; i <= n; i++) scanf("%lld", &a[i].num), a[i].id = i;
  69. for (int i = ; i <= m; i++) {
  70. ll l, r, h;
  71. scanf("%lld%lld%lld", &l, &r, &h);
  72. l++, r++;
  73. ex[i] = edge(l, r, h, i);
  74. }
  75. sort(a + , a + + n, cmp);
  76. sort(ex + , ex + + m, cmp1);
  77. printf("Case %d:\n", cas);
  78. int k = ;
  79. for(int i=;i<=n;i++)
  80. {
  81. while(a[i].num>ex[k].h&&k<=m)
  82. {
  83. ans[ex[k].id] = query(, , n, ex[k].l, ex[k].r);
  84. k++;
  85. }
  86. update(, , n, a[i].id);
  87. }
  88. for (int i = k; i <= m; i++) ans[ex[i].id] = query(, , n, ex[i].l, ex[i].r);//这个注意不要丢掉了!!!
  89. for (int i = ; i <= m; i++) printf("%lld\n", ans[i]);
  90. }
  91. return ;
  92. }

线段树

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <vector>
  7. #define inf 0x3f3f3f3f
  8. #define inf64 0x3f3f3f3f3f3f3f3f
  9. using namespace std;
  10. const int maxn = 1e5 + ;
  11. int n, m, root[maxn], a[maxn], b[maxn], cnt;
  12. int sum[maxn << ], lc[maxn << ], rc[maxn << ];
  13.  
  14. void build(int &rt,int l,int r)
  15. {
  16. rt = ++cnt;
  17. sum[rt] = ;
  18. if (l == r) return;
  19. int mid = (l + r) >> ;
  20. build(lc[rt], l, mid);
  21. build(rc[rt], mid + , r);
  22. // printf("rt=%d l=%d r=%d\n",rt,l,r);
  23. }
  24.  
  25. int update(int rt,int l,int r,int pos)
  26. {
  27. // printf("ww rt=%d l=%d r=%d pos=%d\n", rt, l, r, pos);
  28. int id = ++cnt;
  29. sum[id] = sum[rt] + ;
  30. // printf("rt=%d sum[%d]=%d\n", rt, id, sum[id]);
  31. lc[id] = lc[rt], rc[id] = rc[rt];
  32. if (l == r) return id;
  33. int mid = (l + r) >> ;
  34. // printf("mid=%d rt=%d l=%d r=%d pos=%d\n", mid,rt,l,r,pos);
  35. if (pos <= mid) lc[id] = update(lc[id], l, mid, pos);
  36. else rc[id] = update(rc[id], mid + , r, pos);
  37. // printf("rt=%d l=%d r=%d pos=%d\n", rt, l, r, pos);
  38. return id;
  39. }
  40.  
  41. int query(int l,int r,int u,int v,int h)
  42. {
  43. int mid = (l + r) >> ;
  44. int x = sum[lc[v]] - sum[lc[u]];
  45. if (l == r) return sum[v] - sum[u];
  46. int ans = ;
  47. if (h <= mid) ans = query(l, mid, lc[u], lc[v], h);
  48. else ans = x + query(mid + , r, rc[u], rc[v], h);
  49. return ans;
  50. }
  51.  
  52. int main()
  53. {
  54. int t;
  55. scanf("%d", &t);
  56. for(int cas=;cas<=t;cas++)
  57. {
  58. cnt = ;
  59. scanf("%d%d", &n, &m);
  60. for (int i = ; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
  61. sort(b + , b + + n);
  62. int len = unique(b + , b + + n) - b - ;
  63. build(root[], , len);
  64. // printf("\n\n");
  65. for (int i = ; i <= n; i++) {
  66. a[i] = lower_bound(b + , b + + len, a[i]) - b;
  67. //printf("a[%d]=%d\n", i, a[i]);
  68. root[i] = update(root[i - ], , len, a[i]);
  69. // printf("sum[%d]=%d\n", root[i], sum[root[i]]);
  70. // printf("\n");
  71. }
  72. printf("Case %d:\n", cas);
  73. while(m--)
  74. {
  75. int l, r, h;
  76. scanf("%d%d%d", &l, &r, &h);
  77. l++, r++;
  78. h = upper_bound(b + , b + + len, h) - b - ;
  79. if (h == ) printf("0\n");
  80. else printf("%d\n", query(, len, root[l - ], root[r], h));
  81. }
  82. }
  83. return ;
  84. }

主席树

J - Super Mario HDU - 4417 线段树 离线处理 区间排序的更多相关文章

  1. Super Mario HDU 4417 主席树区间查询

    Super Mario HDU 4417 主席树区间查询 题意 给你n个数(编号从0开始),然后查询区间内小于k的数的个数. 解题思路 这个可以使用主席树来处理,因为这个很类似查询区间内的第k小的问题 ...

  2. E - No Pain No Game 线段树 离线处理 区间排序

    E - No Pain No Game  HDU - 4630 这个题目很好,以后可以再写写.这个题目就是线段树的离线写法,推荐一个博客:https://blog.csdn.net/u01003321 ...

  3. Super Mario HDU - 4417 (主席树询问区间比k小的个数)

    Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...

  4. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. AC日记——Super Mario hdu 4417

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

  6. HDU 3308 线段树单点更新+区间查找最长连续子序列

    LCIS                                                              Time Limit: 6000/2000 MS (Java/Oth ...

  7. Super Mario HDU - 4417 (主席树)

    Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...

  8. hdu 4288 线段树+离线+离散化

    http://acm.hdu.edu.cn/showproblem.php?pid=4288 開始的时候,果断TLE,做的方法是,线段树上只维护%5==3的坐标,比方1 2 3 4 5 6 7  假设 ...

  9. I Hate It HDU - 1754 线段树 单点修改+区间最值

    #include<iostream> #include<cstring> using namespace std; ; int m,n,p; struct node{ int ...

随机推荐

  1. AJ学IOS 之微博项目实战(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类

    AJ分享,必须精品 一:效果对比 当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色 代 ...

  2. HashMap之KeySet分析

    本篇涵盖 1.HashMap并不是用keySet来存储key的原因及证明 2.keySet方法返回后的remove.add操作原理 一.方法作用 概括一下 1.keySet方法返回map中包含的键的集 ...

  3. Docker常用命令--ps/attach/run

    ps查看container 若查看正在运行的container docker ps 查看所有的container docker ps -a run启动容器 第一次启动container docker ...

  4. 10.添加script标签,判断onload是否完成

    class Tools { static loadScript(url, callback) { let old_script = document.getElementById(url); if ( ...

  5. React Hooks: useCallback理解

    useCallback把匿名回调“存”起来 避免在component render时候声明匿名方法,因为这些匿名方法会被反复重新声明而无法被多次利用,然后容易造成component反复不必要的渲染. ...

  6. 2020/4/26 大数据的zookeeper分布式安装

    大数据的zookeeper分布式安装 **** 前面的文章已经提到Hadoop的伪分布式安装.现在就在原有的基础上安装zookeeper. 首先启动Hadoop平台 [root@master ~]# ...

  7. JasperReports入门教程(三):Paramters,Fields和Detail基本组件介绍

    JasperReports入门教程(三):Paramter,Field和Detail基本组件介绍 前言 前两篇博客带领大家进行了入门,做出了第一个例子.也解决了中文打印的问题.大家跟着例子也做出了de ...

  8. JS流程图解决方案GoJS

    GoJs简介 一个实现交互类图表(比如流程图,树图,关系图,力导图等等)的JS库 GoJS依赖于HTML5,所以请保证您的浏览器版本支持HTML5,当然还要加载这个库. 首先个人建议先下载官方实例的 ...

  9. Unity Procedural Level Generator 基础总结与功能优化

    Procedural Level Generator是在Unity应用商店中发布的一款免费的轻量级关卡生成器: 可以直接搜索关键字在应用商店中查找并下载. 和我之前生成关卡的想法不同,这个插件生成地图 ...

  10. liunx系统二进制包安装编译mysql数据库

    liunx系统二进制包安装编译mysql数据库 # 解压二进制压缩包 [root@localhost ~]# tar xf mysql-5.5.32-linux2.6-x86_64.tar.gz -C ...