HDU 4417:Super Mario(主席树)
http://acm.hdu.edu.cn/showproblem.php?pid=4417
题意是:给出n个数和q个询问,每个询问有一个l,r,h,问在[l,r]这个区间里面有多少个数是小于等于h的。
思路:比较裸的主席树,注意题意给的区间是从[0,n-1],一开始看错导致想错了很多东西。询问的时候如果m < h,那么左子树全部都是小于 h 的,就加上左子树的 sum,继续查右子树,否则就查左子树。最后 l == r 的时候要判下 h >= l,因为这个也错了几次。从师兄那里学习到了如果找一个数,如果找不到就返回一个比它小的数,那么可以用 upper_bound() 找到的下标 -1。就不用 lower_bound() 找到后判断等不等于,不等于的话下标 -1 这么麻烦了。(upper_bound()返回的是大于查的数的下标,所以 -1就可以等于或者小于了。)
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define N 100010
struct node
{
int l, r, sum;
}tree[N*];
int root[N], tot, a[N], b[N], cnt; void update(int pre, int &now, int id, int l, int r)
{
now = ++tot; tree[now] = tree[pre];
tree[now].sum++;
if(l == r) return ;
int m = (l + r) >> ;
if(id <= m) update(tree[pre].l, tree[now].l, id, l, m);
else update(tree[pre].r, tree[now].r, id, m + , r);
} int query(int L, int R, int h, int l, int r)
{
int ans = ;
int m = (l + r) >> ;
if(l == r) {
if(h >= l) ans += tree[R].sum - tree[L].sum; // 注意要判下这个
/*
如果区间查询和更新的区间是(0, cnt)的话,那么就可以不用判定这个
因为如果查的区间是(3, 5, 5) 查 2 的话,那么会查到下标 0,
l > h,这个时候就错了
*/
return ans;
}
if(m < h) {
ans += tree[tree[R].l].sum - tree[tree[L].l].sum; // 如果 h > m 的话,左子树全部都小于h,全部都加上
ans += query(tree[L].r, tree[R].r, h, m + , r);
} else {
ans += query(tree[L].l, tree[R].l, h, l, m);
}
return ans;
} void debug(int rt, int l, int r)
{
if(l == r) {
printf("%d : %d\n", l, tree[rt].sum);
return ;
}
int m = (l + r) >> ;
debug(tree[rt].l, l, m);
debug(tree[rt].r, m+, r);
} int main()
{
int t, cas = ;
scanf("%d", &t);
while(t--) {
int n, q;
scanf("%d%d", &n, &q); tot = ; for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + , b + + n);
cnt = unique(b + , b + + n) - b - ;
for(int i = ; i <= n; i++) {
a[i] = lower_bound(b + , b + + cnt, a[i]) - b;
update(root[i-], root[i], a[i], , cnt);
}
debug(root[n], , cnt);
printf("Case %d:\n", cas++);
for(int i = ; i <= q; i++) {
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
l++, r++;
int tmp = upper_bound(b + , b + + cnt, c) - b - ;
// int tmp = lower_bound(b + 1, b + 1 + cnt, c) - b;
// if(b[tmp] != c) tmp--;
// int tmp = lb(c);
printf("%d\n", query(root[l-], root[r], tmp, , cnt));
}
}
return ;
}
HDU 4417:Super Mario(主席树)的更多相关文章
- HDU 4417 Super Mario 主席树
分析:找一个区间里小于等于h的数量,然后这个题先离散化一下,很简单 然后我写这个题主要是熟悉一下主席树,其实这个题完全可以离线做,很简单 但是学了主席树以后,我发现,在线做,一样简单,而且不需要思考 ...
- HDU 4417 Super Mario 主席树查询区间小于某个值的个数
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...
- 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(划分树问题求不大于k的数有多少)
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的最大的一个数字是区间第几小数,即是答案. ...
- HDU 4417 Super Mario ( 离线树状数组 )
把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...
- HDU 4417 Super Mario(划分树+二分)
题目链接 #include <cstdio> #include <cstring> #include <algorithm> using namespace std ...
- 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)Total ...
- hdu 4417 Super Mario (主席树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用 ...
随机推荐
- Git撤销操作命令
使用Git的过程中,失误无法避免,虽然Git很强,但是有些失误,无法挽回.在这里我介绍一些Git的撤销命令. 撤销对文件的修改 如下图所示的情况,你修改了文件,但是不想保存对文件的修改. 根据具体情况 ...
- EF Code First DataAnnotations
Key EF框架要求每个实体必须有主键字段,他需要根据这个主键字段跟踪实体.CodeFirst方法在创建实体时,也必须指定主键字段,默认情况下属性被命名为ID.id或者[ClassName]Id,将映 ...
- Java基础之一组有用的类——Observable和Observer对象(Horrific)
控制台程序. Obserable类提供了一个有趣的机制,可以把类对象中发生的改变通知给许多其他类对象. 对于可以观察的对象来说,类定义中需要使用java.util.Observable类.只需要简单地 ...
- Java-NIO-Selector
扩展阅读: Java NIO类库Selector机制解析(上) Java NIO类库Selector机制解析(下) Java NIO的选择器 三个重要的类: 1,Selector 选择器,完成主要的选 ...
- MVC 学习系列
总是很难说清MVC的概念,即使读了源代码后(读的时候有些东西,理解起来还是有点吃力),也依然能难对整体的每一个具体的原理说的一清二楚.为了达到自己学习的目的,我把自己的学习路线写成文章,一边自己能对M ...
- ofbiz进击 第二节。 control 理解与创建
首先要说的是,学习ofbiz,要去http://ofbiz.apache.org/官网里面,去看右边菜单里 Management Apps 的例子,然后找到类似的页面,去看调用的源码方法. co ...
- vs2010打包系统必备选择.net framework 3.5sp1编译错误的解决方法
利用visual studio 2010进行打包程序,默认安装的是Framework 4.0,如果需要将3.5sp1打包到系统中一起安装(选择了"从与我的应用程序相同的位置下载系统必备组件& ...
- cmd进入某个目录
love you my pig java枚举类 cmd进入某个目录 2011-04-06 15:49:38| 分类: 小知识 | 标签: |字号大中小 订阅 1.开始->运行->C ...
- paper 87:行人检测资源(下)代码数据【转载,以后使用】
这是行人检测相关资源的第二部分:源码和数据集.考虑到实际应用的实时性要求,源码主要是C/C++的.源码和数据集的网址,经过测试都可访问,并注明了这些网址最后更新的日期,供学习和研究进行参考.(欢迎补充 ...
- ORACLE CUP相关
遭遇cpu过多占用,表现为%usr很高,top 或者topas中cpu占用最多的进程为oracle server process. 则根据pid可以找出该pid对应的sql_text select s ...