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 思路: 之前用 ...
随机推荐
- 发现EF中字段错误
在使用EF时,报错: 对一个或多个实体的验证失败.有关详细信息,请参见“EntityValidationErrors”属性 添加一个验证方法: 代码: using System; using Syst ...
- H3C S3600-28TP-SI配置命令
模式分类为:<H3C> 用户视图 [H3C] 系统视图 [H3C-Ethernet1/0/1] 以太网端口视图 [H3C-vlan10] VLAN视图 [H3C-Vl ...
- AWR快照管理
创建快照: SQL> exec dbms_workload_repository.create_snapshot(); 删除快照: SQL> exec dbms_workload_repo ...
- JAX-WS(三)构建简单webservice部署到tomcat上
前言: 虽然构建本地的jax-ws的webservice很简单,但要部署到tomcat上要绕过点弯. tomcat本身和jdk都没有jaw-ws的API,所以部署的时候需要额外做点事情,有两种选择 1 ...
- Emmet 的使用
Emmet 的介绍 Emmet 的前身叫做:Zen Coding,也许熟知旧名的人不在少数.Emmet 一般前端工程师用得比较多,具体它是做什么的,我们通过下面两张 Gif 演示图来说明: Intel ...
- centos 6.4下安装postgresql 9.2
我的linux版本是centos 6.4 ,准备安装postgresql 9.2 根据官方说明: http://www.postgresql.org/download/linux/redhat/ 缺省 ...
- 转:Java实现几种常见排序方法
日常操作中常见的排序方法有:冒泡排序.快速排序.选择排序.插入排序.希尔排序,甚至还有基数排序.鸡尾酒排序.桶排序.鸽巢排序.归并排序等. 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一 ...
- Java的正则表达式
package RegexTest; /** * Created by hu on 2016/3/29. */ /* * Java的正则表达式 在正则表达式中,用\d表示一位数字,如果在其它语言中使用 ...
- .NET 4.0 MemoryCache with SqlChangeMonitor
Summary There isn't a lot of documentation on the internet about how to use the SqlChangeMonitor wit ...
- 验证你的邮箱是不是qq邮箱
Console.WriteLine("请输入你的qq邮箱"); string yx = Console.ReadLine(); int a = yx.LastIndexOf(&qu ...