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(主席树)的更多相关文章

  1. HDU 4417 Super Mario 主席树

    分析:找一个区间里小于等于h的数量,然后这个题先离散化一下,很简单 然后我写这个题主要是熟悉一下主席树,其实这个题完全可以离线做,很简单 但是学了主席树以后,我发现,在线做,一样简单,而且不需要思考 ...

  2. HDU 4417 Super Mario 主席树查询区间小于某个值的个数

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

  3. HDU 4417 Super Mario(划分树)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)

    题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...

  6. HDU 4417 Super Mario ( 离线树状数组 )

    把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...

  7. HDU 4417 Super Mario(划分树+二分)

    题目链接 #include <cstdio> #include <cstring> #include <algorithm> using namespace std ...

  8. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. 主席树:HDU 4417 Super Mario

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. hdu 4417 Super Mario (主席树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用 ...

随机推荐

  1. 读取plist

    - (NSArray *)imageData { if (_imageData == nil) { // 从未初始化 // 初始化数据 // File : 全路径 // NSBundle : 一个NS ...

  2. nsarray排序

    // //  main.m //  05-数组排序 // //  Created by apple on 14-3-21. //  Copyright (c) 2014年 apple. All rig ...

  3. instruments 教程

    https://www.raywenderlich.com/97886/instruments-tutorial-with-swift-getting-started

  4. IIS 相关

    Restart IIS: run "iisreset" command check port usage: netstat -ano How to set up SSL in II ...

  5. C# WebApi传参之Get请求-AJAX

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.  学无止境,精益求精    在介绍本篇博客之前,先来温故下AJax的请求, ...

  6. uiwebview加载中文URL

    uiwebview加载中文URL _paperGamePath = [_paperGamePath stringByAddingPercentEscapesUsingEncoding:NSUTF8St ...

  7. Java基础之访问文件与目录——创建目录(CreatingDirectories)

    控制台程序,使用两种方法来创建目录. import java.nio.file.*; import java.io.IOException; public class CreatingDirector ...

  8. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...

  9. [原创]java WEB学习笔记51:国际化 概述,API 之 locale类,dataFormat类,numberFormat类, MessageFormat类,ResourceBundle 类

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  10. C#: 数据绑定

    数据绑定是分离UI和后端主逻辑程序的一种好的办法.这里总结下TextBox, Label, ComboBox, ListBox, DataGridView的数据绑定 数据绑定都是通过DB来和UI控件的 ...