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 思路: 之前用 ...
随机推荐
- 单源最短路径——Dijkstra算法学习
每次都以为自己理解了Dijkstra这个算法,但是过没多久又忘记了,这应该是第4.5次重温这个算法了. 这次是看的胡鹏的<地理信息系统>,看完之后突然意识到用数学公式表示算法流程是如此的好 ...
- 【转】线程、Thread类和线程终止
一.线程Thread启动 0. Thread类实现了java.lang.Runnable接口,即实现了run方法.虽然在Sun JDK中,start()调用了start0()方法,start0()方法 ...
- Moment.js学习(一)源代码
本篇主要是学习Moment.js.类库源代码如下: 2.4版本. //! moment.js //! version : 2.4.0 //! authors : Tim Wood, Iskren Ch ...
- PostgreSQL Replication之第十五章 与Walbouncer 一起工作
与Walbouncer 一起工作 在本书的最后一章,将引导您通向2014年发布的一个工具,称为walbouncer.本书中的大多数技巧说明了如何复制整个数据库实例,如何分片,等等.在最后一章,是关于w ...
- 转:python webdriver API 之 验证码问题
对于 web 应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防止采用机器猜测 ...
- C++之路进阶——bzoj1823(满汉全席)
F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...
- linux第12天 线程
今天主要学习了共享内存,信号量的封装,还有线程. POSIX线程库 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头的 要使用这些函数库,要通过引入头文<p ...
- JavaOOP QuickHit项目分析
项目需求:游戏等级6级,随机字符串每级长度不同.每升一级减少比较次数,但是字符串长度相应增加!每级总分数不同,如果游戏中途输入错误则游戏退出!玩家每次在规定时间内输入字符串的同时,打印出游戏难度等级. ...
- VS2012发布网站详细步骤
1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击<新建..>,创建新的发布配置文件: 输入你自 ...
- LDA-math-神奇的Gamma函数
http://cos.name/2013/01/lda-math-gamma-function/ 1. 神奇的Gamma函数1.1 Gamma 函数诞生记学高等数学的时候,我们都学习过如下一个长相有点 ...