Super Mario

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

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
 

题目链接:HDU 4417

题意:给你n个数组成的序列求[L,R]中小于等于H的数有多少个,序列下标从0开始

本来对于一般的线段树就直接求和query(1,1,H)即可,但是这样子显然默认的根节点为1即对整颗线段树进行查询,而题目中给的是固定的一段区间,并非朴素线段树默认的的1,N。然后就可以用到主席树了,主席树可以有很多种的区间查询求区间第K大只是其中一种而已吧,这题就是求区间内的区间求和,好像听起来很别扭,就是对一个固定区间内部进行值域求和,本题就是进行区间查询(求和),过程和普通线段树非常相似,在注释中对比了一下普通线段树的姿势……

由于H可能过大,因此要离散化再用lowerbound把H等效为某一个离散化后的高度

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define MID(x,y) ((x+y)>>1) const int N=1e5+7;
struct seg
{
int lson,rson;
int cnt;
};
seg T[N*20];
int root[N],arr[N],tot;
vector<int>vec; void init()
{
CLR(root,0);
tot=0;
vec.clear();
}
void update(int &cur,const int &ori,const int &l,const int &r,const int &val)
{
cur=++tot;
T[cur]=T[ori];
++T[cur].cnt;
if(l==r)
return ;
int mid=MID(l,r);
if(val<=mid)
update(T[cur].lson,T[ori].lson,l,mid,val);
else
update(T[cur].rson,T[ori].rson,mid+1,r,val);
}
int query(const int &S,const int &E,const int &l,const int &r,const int &x,const int &y)
{
if(x<=l&&r<=y)//l<=T[k].l&&T[k].r<=r
return T[E].cnt-T[S].cnt;//return T[k].cnt;
int mid=MID(l,r);
if(y<=mid)//r<=T[k].mid
return query(T[S].lson,T[E].lson,l,mid,x,y);
else if(x>mid)//l>T[k].mid
return query(T[S].rson,T[E].rson,mid+1,r,x,y);
else
return query(T[S].lson,T[E].lson,l,mid, x,mid)+query(T[S].rson,T[E].rson,mid+1,r, mid+1,y);
}
int main(void)
{
int T,n,m,i,l,r,h;
scanf("%d",&T);
for (int q=1; q<=T; ++q)
{
init();
scanf("%d%d",&n,&m);
for (i=1; i<=n; ++i)
{
scanf("%d",&arr[i]);
vec.push_back(arr[i]);
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
int R=vec.size();
for (i=1; i<=n; ++i)
{
arr[i]=lower_bound(vec.begin(),vec.end(),arr[i])-vec.begin()+1;
update(root[i],root[i-1],1,R,arr[i]);
}
printf("Case %d:\n",q);
for (i=0; i<m; ++i)
{
scanf("%d%d%d",&l,&r,&h);
++l;
++r;
int indx=lower_bound(vec.begin(),vec.end(),h)-vec.begin()+1;
//由于H可能过大因此只能找一个最接近的值indx来等效代替
if(vec[indx-1]!=h)
--indx;
printf("%d\n",indx? query(root[l-1],root[r],1,R,1,indx) : 0);
}
}
return 0;
}

HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)的更多相关文章

  1. HDU 4417 Super Mario 主席树查询区间小于某个值的个数

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

  2. HDU 4417 Super Mario 主席树

    分析:找一个区间里小于等于h的数量,然后这个题先离散化一下,很简单 然后我写这个题主要是熟悉一下主席树,其实这个题完全可以离线做,很简单 但是学了主席树以后,我发现,在线做,一样简单,而且不需要思考 ...

  3. HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

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

  4. hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)

    题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...

  5. HDU 4417 Super Mario(划分树)

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

  6. HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)

    题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...

  7. SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)

    DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...

  8. HDU 4417 Super Mario ( 离线树状数组 )

    把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...

  9. HDU 4417 Super Mario(划分树+二分)

    题目链接 #include <cstdio> #include <cstring> #include <algorithm> using namespace std ...

随机推荐

  1. curl请求的url中含有空格

    curl请求的url中含有空格时(例如rul的参数是sql查询语句,url=www.tets.com/query.php?sql=select * from t1),curl_easy_perform ...

  2. [Linux] xargs的- n1参数

    起因在对一堆*.tar.gz文件解压缩时,发现tar xvfz *.tar.gz不管用,一查,原来是tar xvfz *.tar.gz会被shell给拆成tar xvfz a.tar.gz b.tar ...

  3. window常用软件

    ftpserver QQ asc pan 屏保 view putty 迅雷 teamviewer绿色 teamviewer单文件 魔方 chrome winscp WinRAR xshell 鲁大师 ...

  4. linux环境下配置虚拟主机域名

    linux环境下面配置虚拟主机域名 第一步:在root目录下面(即根目录)ls(查看文件)cd进入etc目录find hosts文件vi hosts 打开hosts文件并进行编辑在打开的文件最下面添加 ...

  5. linux下常见的文件夹含义

    1./bin :获得最小的系统可操作性所需要的命令2./boot :内核和加载内核所需的文件3./dev :终端.磁盘.调制解调器等的设备项4./etc :关键的启动文件和配置文件5./home :用 ...

  6. Maven使用笔记(五)Sonatype Nexus 搭建Maven 私服

    1. 为什么使用Nexus 如果没有私服,我们所需的所有构件都需要通过maven的中央仓库和第三方的Maven仓库下载到本地, 而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载 ...

  7. win8 鼠标失灵解决办法

    前几天 也没更新,却不知道突然win8 pro 失灵了,是不是ms 后台运行的也不确定,不过更新之后就可以用了. 经供参考: 更新前: 更新后: 我的主板是华硕的,有时候需要重启几次鼠标才显示出来

  8. laravel数据库查询是use方法的使用

    ){                return $query->where('effectivetime','<',date('Y-m-d'));             }else{ ...

  9. 随机sample文件Python程序

    经常遇到由于样本巨大,需要sample一部分文件进行案例分析的情况,下面的程序主要为了随机抽取一个大文件中的N行. #!/usr/bin/python # -*- coding: <encodi ...

  10. poj 2236 并查集

    并查集水题 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...