Super Mario

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9714    Accepted Submission(s): 4113

Problem Description
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (the length is n), on every integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.
Input
The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Output
For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.
Sample Input
1
10 10
0 5 2 7 5 4 3 8 7 7
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3

Sample Output
Case 1:
4
0
0
3
1
2
0
1
5
1
题意:给出n个数组成的无序序列,序列中的每个数表示一块砖的高度,有m个查询,每个查询三个数,前两个数表示序列的一个子区间,第三个数表示马里奥能跳到的最大高度,问你在这个子区间中,马里奥共能跳过多少个砖头。
题解:我们可以这么想,对于一个子区间,我们将它按从小到大排好序,然后对这个区间进行二分,找到这个区间排序后的中间值,若马里奥能跳过的最大高度大于中间值,则可得知马里奥可以跳过排序后区间的前半段,然后对区间后边段进行二分;若最大高度小于中间值,则对排序后区间前半部分进行二分,一直持续二分下去,直到结束。最终二分的停止位置就是可以被跳过的砖的数量。
  而每次查询都对子区间进行排序的话时间复杂度太高,所以我们可以用划分树对区间进行维护。划分树的作用就是查找区间当中的第k大的值,这里我就不讲解划分树了,不会的可以先去学一学。每次二分都用划分树找出当前的第mid个值,然后与马里奥能跳过的最大值进行比较。
具体看代码:
  1 #include<iostream>
  2 #include<iomanip>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<string>
  6 #include<cmath>
  7 #include<algorithm>
  8 #include<fstream>
  9 #include<stack>
 10 #include<climits>
 11 #include<queue>
 12 #define eps 1e-7
 13 //#define ll long long
 14 #define inf 0x3f3f3f3f
 15 #define pi 3.141592653589793238462643383279
 16 using namespace std;
 17 const int MAXN = 1e5 + 7;
 18 int n,m,tree[20][MAXN],sorted[MAXN],toleft[20][MAXN];
 19
 20 void build(int l,int r,int dep)  //建立划分树
 21 {
 22     if(l == r) return;
 23
 24     int mid = (l + r)>>1;
 25     int lpos = l;
 26     int rpos = mid + 1;
 27     int same = mid - l + 1;
 28     for(int i=l; i<=r; ++i)
 29         if(tree[dep][i] < sorted[mid])
 30             same--;
 31
 32     for(int i=l; i<=r; ++i)
 33     {
 34         if(tree[dep][i] < sorted[mid])
 35             tree[dep+1][lpos++] = tree[dep][i];
 36         else if(tree[dep][i] == sorted[mid] && same > 0)
 37         {
 38             tree[dep+1][lpos++] = tree[dep][i];
 39             same--;
 40         }
 41         else tree[dep+1][rpos++] = tree[dep][i];
 42         toleft[dep][i] = toleft[dep][l-1] + lpos - l;
 43     }
 44
 45     build(l,mid,dep+1);
 46     build(mid+1,r,dep+1);
 47 }
 48
 49 int query(int l,int r,int L,int R,int dep,int k)  //划分树查询区间第k大值
 50 {
 51     if(l == r)
 52         return tree[dep][l];
 53     int mid = (L + R) >> 1;
 54     int cnt = toleft[dep][r] - toleft[dep][l-1];
 55
 56     int newl,newr;
 57     if(cnt >= k)
 58     {
 59         newl = L + toleft[dep][l-1] - toleft[dep][L-1];
 60         newr = newl + cnt - 1;
 61         return query(newl,newr,L,mid,dep+1,k);
 62     }
 63     else
 64     {
 65         newr = r + (toleft[dep][R] - toleft[dep][r]);
 66         newl = newr - r + l + cnt;
 67         return query(newl,newr,mid+1,R,dep+1,k - cnt);
 68     }
 69 }
 70
 71 int solve(int ll,int rr,int h)    //计算区间当中可以被跳过的砖头的数量
 72 {
 73     int l = 1,r = (rr-ll) + 1,ans=0;
 74     while(l <= r)
 75     {
 76         int mid = (l + r) >> 1;  //取当前区间的中间值下标
 77         if(query(ll,rr,1,n,0,mid) <= h)  //划分树查询得到中间值,若中间值 <= h
 78         {
 79             l = mid + 1; //缩小区间
 80             ans = mid;
 81         }
 82         else r = mid - 1;
 83     }
 84     return ans;
 85 }
 86
 87 int main()
 88 {
 89     int t,cnt = 0;
 90     cin>>t;
 91     while(t--)
 92     {
 93         cin>>n>>m;
 94         for(int i=1; i<=n; ++i)
 95         {
 96             scanf("%d",&sorted[i]);
 97             tree[0][i] = sorted[i];
 98         }
 99         sort(sorted+1, sorted+1+n);
100         build(1,n,0);
101
102         printf("Case %d:\n",++cnt);
103         int l,r,h;
104         while(m--)
105         {
106             scanf("%d%d%d",&l,&r,&h);
107             printf("%d\n",solve(l+1,r+1,h));
108         }
109     }
110     return 0;
111 }

转载于:https://www.cnblogs.com/tuyang1129/p/10009807.html

hdu4417(Super Mario)—— 二分+划分树相关推荐

  1. HDU4417 Super Mario (主席树模板)

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

  2. [HDU4417]Super Mario

    [HDU4417]Super Mario Mario is world-famous plumber. His "burly" figure and amazing jumping ...

  3. HDU4417 Super Mario(离线树状数组或者主席树+二分)

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

  4. HDU-4417 Super Mario

    Super Mario Mario is world-famous plumber. His "burly" figure and amazing jumping ability ...

  5. HDU 4417 Super Mario(线段树)

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

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

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  7. hdu4417 Super Mario(树状数组+离线区间操作)

    题目链接 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jum ...

  8. HDU4417 Super Mario 主席树

    欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU4417 题意概括 给定一个长度为n的区间,同时给出m个询问,每次询问在区间[l,r]中有多少个数小于或 ...

  9. 【可持久化线段树】【主席树】[HDU4417]Super Mario

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

最新文章

  1. 代码错误信息,微信报错
  2. 用python画月亮的代码-用Python画一个超级月亮
  3. 使用 Eclipse Memory Analyzer 进行堆转储文件分析
  4. python--通过xpath相对节点位置查找元素(续)
  5. RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的设置...
  6. activemq的使用经验
  7. 《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一1.2.4 存储...
  8. 01_项目需求与实体分析(servlet+java bean+jsp的商城教程)
  9. 大疆文档(2)-指南
  10. html语言的特殊符号,特殊符号
  11. 软考-嵌入式系统设计师-笔记:嵌入式系统的项目开发与维护
  12. [不务正业系列] 致-陪我们长大的周董
  13. jpeg格式转pdf格式的简单方法
  14. Activiti 用户绑定申请审批全流程演示
  15. 剑指offer 62题 约瑟夫环
  16. 锤子m1l 刷android7.0,锤子M1/M1L收到 Smartisan OS 3.7.0 更新推送
  17. 单机斗地主之完整功能初版
  18. Mac 硬件驱动(.kext)安装方法
  19. 王者荣耀角色注销后我的服务器列表怎么删除,王者荣耀账号怎么注销 角色删除流程要求...
  20. ThinkPad触摸板开启或者关闭方法

热门文章

  1. fedora nginx php,在fedora16下安裝nginx + php-fpm
  2. pandas 导入excel_三行Python代码,合并多个Excel文件
  3. matlab中input输入多个数_python怎么一次输入两个数
  4. android ontouchevent 坐标,onTouchEvent(一) 你所必须知道的坐标详解
  5. php5.3 本地调试,WIN7下PHP 5.3.27和PHPStorm6调试
  6. mapbox 修改初始位置_《绝地求生》实用的键位改键推荐 | 哪些不合理的初始键位需要更改?...
  7. linux删除静态arp,Linux如何清理ARP缓存?
  8. chips cope_Android P:Chips and ChipGroup
  9. android oreo_Android Oreo画中画
  10. adalm pluto_Apache Pluto和PHP集成示例教程