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个值,然后与马里奥能跳过的最大值进行比较。
 
具体看代码:
 #include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
#include<fstream>
#include<stack>
#include<climits>
#include<queue>
#define eps 1e-7
//#define ll long long
#define inf 0x3f3f3f3f
#define pi 3.141592653589793238462643383279
using namespace std;
const int MAXN = 1e5 + ;
int n,m,tree[][MAXN],sorted[MAXN],toleft[][MAXN]; void build(int l,int r,int dep) //建立划分树
{
if(l == r) return; int mid = (l + r)>>;
int lpos = l;
int rpos = mid + ;
int same = mid - l + ;
for(int i=l; i<=r; ++i)
if(tree[dep][i] < sorted[mid])
same--; for(int i=l; i<=r; ++i)
{
if(tree[dep][i] < sorted[mid])
tree[dep+][lpos++] = tree[dep][i];
else if(tree[dep][i] == sorted[mid] && same > )
{
tree[dep+][lpos++] = tree[dep][i];
same--;
}
else tree[dep+][rpos++] = tree[dep][i];
toleft[dep][i] = toleft[dep][l-] + lpos - l;
} build(l,mid,dep+);
build(mid+,r,dep+);
} int query(int l,int r,int L,int R,int dep,int k) //划分树查询区间第k大值
{
if(l == r)
return tree[dep][l];
int mid = (L + R) >> ;
int cnt = toleft[dep][r] - toleft[dep][l-]; int newl,newr;
if(cnt >= k)
{
newl = L + toleft[dep][l-] - toleft[dep][L-];
newr = newl + cnt - ;
return query(newl,newr,L,mid,dep+,k);
}
else
{
newr = r + (toleft[dep][R] - toleft[dep][r]);
newl = newr - r + l + cnt;
return query(newl,newr,mid+,R,dep+,k - cnt);
}
} int solve(int ll,int rr,int h) //计算区间当中可以被跳过的砖头的数量
{
int l = ,r = (rr-ll) + ,ans=;
while(l <= r)
{
int mid = (l + r) >> ; //取当前区间的中间值下标
if(query(ll,rr,,n,,mid) <= h) //划分树查询得到中间值,若中间值 <= h
{
l = mid + ; //缩小区间
ans = mid;
}
else r = mid - ;
}
return ans;
} int main()
{
int t,cnt = ;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=; i<=n; ++i)
{
scanf("%d",&sorted[i]);
tree[][i] = sorted[i];
}
sort(sorted+, sorted++n);
build(,n,); printf("Case %d:\n",++cnt);
int l,r,h;
while(m--)
{
scanf("%d%d%d",&l,&r,&h);
printf("%d\n",solve(l+,r+,h));
}
}
return ;
}

hdu4417(Super Mario)—— 二分+划分树的更多相关文章

  1. HDU 4417 Super Mario (划分树)(二分)

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

  2. HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)

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

  3. HDU4417 Super Mario(主席树)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4417 Description Mario is world-famous plumber. ...

  4. [HDU4417]Super Mario(主席树+离散化)

    传送门 又是一道主席树模板题,注意数组从0开始,还有主席树耗费空间很大,数组开大点,之前开小了莫名其妙TLE.QAQ ——代码 #include <cstdio> #include < ...

  5. HDU--4417 Super Mario (主席树模版题)

    题目链接 题目让求 L R区间 不大于H 的数有多少 数据太大需要离散化 #include<bits/stdc++.h> using namespace std; #define maxn ...

  6. HDU-4417 Super Mario,划分树+二分!

    Super Mario 这个题也做了一天,思路是很清晰,不过二分那里写残了,然后又是无限RE.. 题意:就是查询区间不大于k的数的个数. 思路:裸划分树+二分答案.将区间长度作为二分范围.这个是重点. ...

  7. hdu4417 Super Mario 树阵离线/划分树

    http://acm.hdu.edu.cn/showproblem.php?pid=4417 Super Mario Time Limit: 2000/1000 MS (Java/Others)    ...

  8. hdu-4417 Super Mario(树状数组 + 划分树)

    题目链接: Super Mario Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Other ...

  9. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

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

随机推荐

  1. SQL 变量、 运算符、 if 、while

    变量: SQL语言也跟其他编程语言一样,拥有变量.分支.循环等控制语句. 在SQL语言里面把变量分为局部变量和全局变量,全局变量又称系统变量. 局部变量: 使用declare关键字给变量声明,语法非常 ...

  2. intellij idea 添加模板语句

    1.说明 在intellij idea 中有很多模板语句可有使用,比如:输入sout,就可以直接生成 System.out.println();代码, 输入psvm,就可以直接生成main方法,类似这 ...

  3. android笔记:Service

    服务:在后台运行,没有界面的组件. 服务生命周期如下: 两种启动方式: 1.startService(): onCreate()-->onStartCommand()-->onDestro ...

  4. hdoj1087 (DP--LIS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 思路:这题很简单了,纯LIS的解法,没有一点变形,由于数据小,使用O(n^2)LIS解法就足够了 ...

  5. Django的cookie学习

    为什么要有cookie,因为http是无状态的,每次请求都是独立的,但是我们还需要保持状态,所以就有了cookie cookie就是保存在客户端浏览器上的键值对,别人可以利用他来做登陆 rep = r ...

  6. windows系统如何真正隐藏文件夹[转载]

    方法一(推荐)eg:现需隐藏e盘bak目录下的tools文件夹e:\bak\tools运行:cmd键入:attrib +s +a +h +r e:\bak\tools然后,你再进去看e盘bak目录下, ...

  7. LocalBroadcastManager 的使用

    一.使用本地广播发送一条广播(本例为自己发送自己接收,本地广播也可以是其他应用接收)然后接收到广播时回调Receiver类中的回调方法onReceive()在此方法中自定义发出通知 代码 packag ...

  8. ubuntu系统:插入优盘read-only file system

    http://sharadchhetri.com/2013/12/19/how-to-fix-read-only-usb-pen-drive-in-ubuntu/ To fix USB pen dri ...

  9. mysql中GROUP_CONCAT的使用

    现在有三个表,结构如下: cate表 CREATE TABLE `cate` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', ...

  10. 删除SVN版本控制目录

    @echo On @Rem 删除SVN版本控制目录 @PROMPT [Com] @for /r . %%a in (.) do @if exist "%%a\.svn" rd /s ...