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个询问.每次问你一段区间内不大于某个数字(不一定是给你的数字)的个数 直接线段树没法做,因为每次给你的数字不一样,父节点无法统计.但是离线一 ...
随机推荐
- Java排序算法(二)
java排序算法(二) 二.改进排序算法 2.1希尔排序 定义:希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. ...
- 上机练习2 生成计算机ID
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- KBEngine warring项目源码阅读(二) 登录和baseapp的负载均衡
原本不打算把登录拿出来写的,但是阅读登录部分的代码的时候发现登录和注册还不太一回事,因为登录涉及到分配baseapp的ip,负载均衡的实现,所以水一下. 流程图: 和上次一样,先是找unity控件 找 ...
- Atcoder训练计划
争取三天做完一套吧,太简单的就写一句话题解吧(其实也没多少会做的). 自己做出来的在前面用*标记 agc007 *A - Shik and Stone 暴力dfs即可,直接判断个数 *B - Cons ...
- HTTPS与SSL(一)
1. HTTPS HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版 ...
- nvcc 编译显示寄存器使用情况
NVCC Compiler 里面增加 Command line pattern中${COMMAND}后 增加选项: --ptxas-options=-v
- font:inherit
font:inherit 字体的设置 设置所有元素的字体保持一致: 所有元素:*{font:inherit;} /* IE8+ */ body体用percent:body{font:100%/1 sa ...
- 「转」sqlalchemy 0.9.8 多对多级联删除
转自知乎 http://www.zhihu.com/question/21050551 有 A,B,C,AB,AC五张表 class A(base): __tablename__ = "a& ...
- Webstrom使用手册小记
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10883350.html,多谢~=.= 1.从git上拉取项目 或者 2.切换分支(webstro ...
- innobackupex实现对MySQL的增量备份与还原
备份增量备份是基于完整备份的,所以我们需要先做一次完整备份: innobackupex --defaults-file=/etc/my.cnf --user root --password cheng ...