HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)
Super Mario
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5101 Accepted Submission(s): 2339
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.)
题目链接: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(主席树求区间内的区间查询+离散化)的更多相关文章
- HDU 4417 Super Mario 主席树查询区间小于某个值的个数
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...
- HDU 4417 Super Mario 主席树
分析:找一个区间里小于等于h的数量,然后这个题先离散化一下,很简单 然后我写这个题主要是熟悉一下主席树,其实这个题完全可以离线做,很简单 但是学了主席树以后,我发现,在线做,一样简单,而且不需要思考 ...
- HDU 4417 Super Mario(划分树问题求不大于k的数有多少)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)
题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...
- 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 ( 划分树+二分 / 树状数组+离线处理+离散化)
题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...
- SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- HDU 4417 Super Mario ( 离线树状数组 )
把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...
- HDU 4417 Super Mario(划分树+二分)
题目链接 #include <cstdio> #include <cstring> #include <algorithm> using namespace std ...
随机推荐
- curl请求的url中含有空格
curl请求的url中含有空格时(例如rul的参数是sql查询语句,url=www.tets.com/query.php?sql=select * from t1),curl_easy_perform ...
- [Linux] xargs的- n1参数
起因在对一堆*.tar.gz文件解压缩时,发现tar xvfz *.tar.gz不管用,一查,原来是tar xvfz *.tar.gz会被shell给拆成tar xvfz a.tar.gz b.tar ...
- window常用软件
ftpserver QQ asc pan 屏保 view putty 迅雷 teamviewer绿色 teamviewer单文件 魔方 chrome winscp WinRAR xshell 鲁大师 ...
- linux环境下配置虚拟主机域名
linux环境下面配置虚拟主机域名 第一步:在root目录下面(即根目录)ls(查看文件)cd进入etc目录find hosts文件vi hosts 打开hosts文件并进行编辑在打开的文件最下面添加 ...
- linux下常见的文件夹含义
1./bin :获得最小的系统可操作性所需要的命令2./boot :内核和加载内核所需的文件3./dev :终端.磁盘.调制解调器等的设备项4./etc :关键的启动文件和配置文件5./home :用 ...
- Maven使用笔记(五)Sonatype Nexus 搭建Maven 私服
1. 为什么使用Nexus 如果没有私服,我们所需的所有构件都需要通过maven的中央仓库和第三方的Maven仓库下载到本地, 而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载 ...
- win8 鼠标失灵解决办法
前几天 也没更新,却不知道突然win8 pro 失灵了,是不是ms 后台运行的也不确定,不过更新之后就可以用了. 经供参考: 更新前: 更新后: 我的主板是华硕的,有时候需要重启几次鼠标才显示出来
- laravel数据库查询是use方法的使用
){ return $query->where('effectivetime','<',date('Y-m-d')); }else{ ...
- 随机sample文件Python程序
经常遇到由于样本巨大,需要sample一部分文件进行案例分析的情况,下面的程序主要为了随机抽取一个大文件中的N行. #!/usr/bin/python # -*- coding: <encodi ...
- poj 2236 并查集
并查集水题 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring& ...