HDU:4417-Super Mario(离线线段树)
Super Mario
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
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个水管,每个水管都有高度,马里奥要从水管a走到水管b,此时马里奥能跨过的高度为h,问你在区间[a,b]之间水管高度不大于h的有多少个。
- 这个题一看就知道是线段树,但是线段树每一个节点记录的状态肯定不能记录多个高度的数量。很容易想到解决办法,没办法记录多个高度,那就从低的高度开始累加,所以在面对询问的时候将询问按照高度排序,在询问之前更新数量,插入不大于当前询问高度的水管,然后每次用线段树记录当前答案存下来,然后再按照之前询问的顺序输出就行了。
- 为了不TLE,要记录水管的位置,然后排序,按照顺序插入。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<string>
using namespace std;
const int maxn = 1e5+100;
struct tree {
int cnt,l,r;
}node[maxn<<2];
struct Brick{
int va,pos;
friend bool operator < (const Brick a, const Brick b){
return a.va < b.va;
}
}brick[maxn];
int n,m,ans[maxn];
struct Query{
int l,r,h,pos;
} qu[maxn];
bool cmp(Query a,Query b){
return a.h < b.h;
}
void init(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&brick[i].va);
brick[i].pos = i;
}
for(int i=0;i<m;i++){
scanf("%d%d%d",&qu[i].l,&qu[i].r,&qu[i].h);
qu[i].pos = i;
}
sort(brick,brick+n);//水管排序
sort(qu,qu+m,cmp);//询问排序
}
void build(int root,int l,int r){
node[root].cnt = 0;
node[root].l = l;
node[root].r = r;
if(l == r)
return ;
int mid = (l+r) >> 1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
}
void insert_tree(int pos,int root,int l,int r){
node[root].cnt++;
if(l == r)
return ;
int mid = (l+r)>>1;
if(mid < pos)
insert_tree(pos,root<<1|1,mid+1,r);
else
insert_tree(pos,root<<1,l,mid);
}
int query(int l,int r,int root,int L,int R){
if(l == L && r == R)
return node[root].cnt;
int mid = (L + R)>>1;
if(mid >= r)
return query(l,r,root<<1,L,mid);
else if(mid < l)
return query(l,r,root<<1|1,mid+1,R);
else
return query(l,mid,root<<1,L,mid) + query(mid+1,r,root<<1|1,mid+1,R);
}
void get_ans(){
int k = 0;
for(int i=0;i<m;i++){
while(k<n){
if(brick[k].va <= qu[i].h){
insert_tree(brick[k].pos,1,0,n-1);//先插入
k++;
}
else
break;
}
int Ans = query(qu[i].l,qu[i].r,1,0,n-1);//再询问
ans[qu[i].pos] = Ans;//把答案给记录下来
}
}
void Print(){
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
}
int main(){
int t,T = 1;
scanf("%d",&t);
while(t--){
printf("Case %d:\n",T++);
init();
build(1,0,n-1);
get_ans();
Print();
}
return 0;
}
HDU:4417-Super Mario(离线线段树)的更多相关文章
- hdu 4417 Super Mario 离线线段树
思路:将点按值从小到大排序,询问按h从小到大排序. 在建立线段树,按h的大小更新树并得到该次查询的结果! 代码如下: #include<iostream> #include<stdi ...
- HDU 4417 Super Mario(线段树)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 4417 Super Mario (划分树)(二分)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 4417 Super Mario ( 离线树状数组 )
把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...
- hdu 4417 Super Mario (主席树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用 ...
- HDU 4417 Super Mario(主席树 区间不超过k的个数)题解
题意:问区间内不超过k的个数 思路:显然主席树,把所有的值离散化一下,然后主席树求一下小于等于k有几个就行.注意,他给你的k不一定包含在数组里,所以问题中的询问一起离散化. 代码: #include& ...
- HDU 5700 区间交 离线线段树
区间交 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5700 Description 小A有一个含有n个非负整数的数列与m个区间.每个区间可以表示为 ...
- HDU 4417 Super Mario(2012杭州网络赛 H 离线线段树)
突然想到的节约时间的方法,感觉6翻了 给你n个数字,接着m个询问.每次问你一段区间内不大于某个数字(不一定是给你的数字)的个数 直接线段树没法做,因为每次给你的数字不一样,父节点无法统计.但是离线一 ...
随机推荐
- jquery的.get方法说解
·Customer类 public class Customer { public int Unid { get; set; } public string CustomerName { get; s ...
- Java编程中中文乱码问题的研究及解决方案
0 引言 Java最大的特性是与平台的无关性及开发环境的多样性.字符串被Java应用程序转化之前,是根据操作系统默认的编码方式编码.Java语言内部采用Unicode编码,它是定长双字节编码,即任何符 ...
- jQuery获取url
JS获取当前页面的URL信息 设置或获取对象指定的文件名或路径. <script> alert(window.location.pathname) </script> 设置或获 ...
- android中AudioRecord使用
一 什么是音频的采样率和采样大小 自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码.即PCM编码.PCM通过抽样.量化.编码三个步骤将连续变化的模拟信号转换为数字编码. 抽样:在 ...
- AngularJS(九):路由
本文也同步发表在我的公众号“我的天空” AngularJS路由 AngularJS路由可以让我们通过不同的URL访问不同页面(似乎是废话),其价值主要体现在单页面的web应用中(single page ...
- js为页面元素添加水印
近期有需求为页面部分区域添加上水印,通过在网上找到了js为页面添加水印的方法,后来经过自己的改进,可以实现为页面部分元素添加水印,最终效果如下图: 代码如下: function watermark(s ...
- 【干货】Html与CSS入门学习笔记1-3
从23号开始用了4天时间看完了<Head First Html与CSS>这本书,本书讲解方式深入浅出,便于理解,结合习题,便于记忆,是一本不错的入门书.下面是本书的学习笔记: 一.认识HT ...
- EPSG:4326
简单说,"EPSG:4326"指的就是WGS84坐标系 参考 http://blog.csdn.net/cloverwindy/article/details/8663968 AU ...
- Shape详解
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...
- Masonry 等间隔或等宽高排列多个控件
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...