博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu4417
阅读量:6424 次
发布时间:2019-06-23

本文共 1616 字,大约阅读时间需要 5 分钟。

题意

给出一些数,每次询问某一区间有多少数不超过 \(x\)

分析

题目本身没什么好说,这道题有多种解法。

  1. 主席树模板题
  2. 树状数组

树状数组的解法还是蛮有启发性的,首先如果数据不大,我们可以用二维树状数组去做,将每个数的大小看做第二维。但可惜,数据很大,这样显然会爆掉内存。可以换个思路,我们真的需要第二维吗,有没有什么办法去掉第二维呢,答案是肯定的,考虑将查询按数的大小排序,当遍历到一个查询时,树状数组中更新所有不超过这个数的大小的位置的值(将对应的位置加 1 ),此时再去查询,直接就是某个区间的和,因为我们查询的数是按从小到大排序的,所有到后面的查询,前面的数仍然满足条件。

code

#include
typedef long long ll;using namespace std;const int MAXN = 1e5 + 10;struct AA { int h, i; bool operator < (const AA& o) const { return h < o.h; }}a[MAXN];struct BB { int l, r, h, i; bool operator < (const BB& o) const { return h < o.h; }}b[MAXN];int ans[MAXN], f[MAXN];void update(int x) { while(x < MAXN) { f[x]++; x += x & -x; }}int query(int x) { int res = 0; while(x) { res += f[x]; x -= x & -x; } return res;}int main() { int T, kase = 1; scanf("%d", &T); while(T--) { int n, m; memset(f, 0, sizeof f); scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%d", &a[i].h); a[i].i = i; } for(int i = 0; i < m; i++) { scanf("%d%d%d", &b[i].l, &b[i].r, &b[i].h); b[i].i = i; } sort(a, a + n); sort(b, b + m); for(int i = 0, j = 0; i < m; i++) { while(j < n && a[j].h <= b[i].h) { update(a[j].i + 1); j++; } ans[b[i].i] = query(b[i].r + 1) - query(b[i].l); } printf("Case %d:\n", kase++); for(int i = 0; i < m; i++) printf("%d\n", ans[i]); } return 0;}

转载于:https://www.cnblogs.com/ftae/p/7758496.html

你可能感兴趣的文章
升級 Centos 6.5 的 php 版本
查看>>
后海日记(2)
查看>>
c标准库函数 strcat
查看>>
图算法 单源最短路径 Dijkstra算法(邻接表/邻接矩阵+优先队列STL)
查看>>
区块链技术对未来的影响
查看>>
解决iphone横屏时字体变大问题或者内容大小不一样等...
查看>>
教程-Delphi资源文件(全面分析于使用)
查看>>
问题-百度云同步盘登陆时提示155010错误
查看>>
构建基于分布式SOA架构的统一身份认证体系
查看>>
Java之word导出下载
查看>>
CocoaPods升级安装三方库报错
查看>>
[数]来自亮亮OJ的五道数学题
查看>>
Mysql容器启动失败-解决方案
查看>>
webpy猫腻之session with reloader
查看>>
Questions2-touchpad-linux
查看>>
http://api.36wu.com/
查看>>
[leetcode-463-Island Perimeter]
查看>>
Java IO整理
查看>>
视图间坐标转换
查看>>
一个最小化的SpringBoot项目
查看>>