HDU 4417 Super Mario // 线段树
2015-08-10 22:40
330 查看
题目描述
HDU 4417 Super Mario解题思路
题目大意:查询区间 [l, r] 有多少个数 <= h.
之前只接触过一点线段树, 所以还是来一发线段树吧= =|
参考代码
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #define lson rt<<1 #define rson rt<<1|1 #define mid ((l+r)>>1) using namespace std; typedef vector<int> vi; const int MAX_N = 100010; int num[MAX_N]; vi v[MAX_N << 2]; void build(int l, int r, int rt) {//建树 v[rt].clear(); for(int i = l; i <= r; i++)// 把 l 到 r 的元素都存在vector中 v[rt].push_back(num[i]); sort(v[rt].begin(), v[rt].end());//排序方便后面二分查找 if(l == r) return ; build(l, mid, lson); build(mid+1, r, rson); } int query(int L, int R, int val, int l, int r, int rt) {//查询 if(L <= l && r <= R) {//当查待询区间[L, R] 完全包含 [l, r] 则返回该区间的结果 vi::iterator it; it = upper_bound(v[rt].begin(), v[rt].end(), val); //找到第一个比val大的位置 return it - v[rt].begin();//相减得到小于等于val的个数 } int ans = 0; if(L <= mid) ans += query(L, R, val, l, mid, lson); // 有一部分区间在 [l, mid] 之间 if(mid < R) ans += query(L, R, val, mid+1, r, rson); //有一部分在 [mid+1, r] 之间 return ans; } int main() { int T, l, r, h, n, m; while(~scanf("%d", &T)) { for(int k = 1; k <= T; k++) { scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &num[i]); build(1, n, 1); printf("Case %d:\n", k); while(m--) { scanf("%d %d %d", &l, &r, &h); printf("%d\n", query(l+1, r+1, h, 1 , n , 1)); } } } return 0; }
相关文章推荐
- [数论]小于n且与n互素的个数(欧拉函数)
- Math.abs为Integer.Min_VALUE返回错误的值
- MapReduce 工作机制剖析
- 使用序列化实现对象的拷贝
- 判断一周的某一天的函数接口
- 【特种兵PPT教程】特种兵PPT知识分享——如何用PPT快速抠图?
- 粒子群算法 Particle Swarm Optimization, PSO(转贴收藏)
- Unicode与Ansi及UTF8与Ansi之间的转换
- JQuery AJAX 方法总结:
- php学习笔记--面向对象oop及注意点
- 计算两个坐标点之间的距离
- Java笔试面试题005
- UIlabel自适应高度和UITableViewCell自适应高度
- QString与string的相互转换
- Qt 的QString类的使用
- ajax+servlet的网站架构
- oracle死锁解决方法
- Redis学习笔记
- 在linux下使终端和vi能输入中文
- OC之NSString2