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. OC内存管理--zombie对象

    当我们对于内存进行手动管理的时候,会出现两种错误:一种是野指针错误,一种则为内存泄露.这两点也是我们去管理内存时最终要解决的问题. 内存泄漏是指:不在使用的对象,一直保留在内存中未被销毁,一直占有着内 ...

  2. /bin/dd if=/path/to/source-file of=/path/to/backup-file

    [root@ok virhost]# qemu-img info 05t.img image: 05t.img file format: raw virtual size: 10G (10737418 ...

  3. ytu 2011: C语言实验——找中间数(水题)

    2011: C语言实验——找中间数 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 212  Solved: 122[Submit][Status][Web ...

  4. AppPoolService-IIS应用程序池辅助类(C#控制应用程序池操作)

    using System.Collections.Generic; using System.DirectoryServices; using System.Linq; using Microsoft ...

  5. hdu 1757 矩阵快速幂 **

    一看正确率这么高,以为是水题可以爽一发,结果是没怎么用过的矩阵快速幂,233 题解链接:点我 #include<iostream> #include<cstring> ; us ...

  6. 理解HTTP session原理及应用

    转自:http://www.2cto.com/kf/201206/135471.html 一.术语session在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣 ...

  7. oracle中如何对字符串进行去除空格的方法

    oracle中如何对字符串进行去除空格的方法 今天学习了一下oracle中如何对字符串进行去除空格的方法,这里总结一下.了解到的方法主要有两种:Trim函数以及Replace函数.下面我详细的介绍一下 ...

  8. Python实践:开篇

    一.概述 Python实践 是应用Python解决实际问题的案例集合,这些案例中的Python应用通常 功能各异.大小不一. 该系列文章是本人应用Python的实践总结,会不定期更新. 二.目录 Py ...

  9. 数据仓库原理<1>:数据库与数据仓库

    updated 2015.8.27 updated 2015.8.26 updated 2015.8.23 0. 说明 <数据仓库原理>系列博文,是笔者在学习数据仓库与商业智能时的读书笔记 ...

  10. JavaScript事件流

    什么是JS事件流 早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素:而Netscape公司的Netscape Navigator则是朝相反的方向传播, 也就是从目标元素开始 ...