3 2 5 2 3 6 2
0 2HintIn this test case, there are 3 trees whose heights are 5 2 3. For the query 6, if CodeFamer cuts the tree whose height is not large than 6, the height form of left trees are -1 -1 -1(-1 means this tree was cut). Thus there is 0 block. For the query 2, if CodeFamer cuts the tree whose height is not large than 2, the height form of left trees are 5 -1 3(-1 means this tree was cut). Thus there are 2 blocks.
STL中关于二分查找的函数有三个lower_bound 、upper_bound 、binary_search 。这三个函数都运用于有序区间(当然这也是运用二分查找的前提),下面记录一下这两个函数。
ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。
ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于值val的位置。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 100005;
int n, q;
int h[maxn], ans[maxn], vis[maxn];
pair<int, int> p[maxn];
int main() {
while(scanf("%d %d", &n, &q) != EOF) {
for(int i = 1; i <= n; i++) {
scanf("%d", h + i);
p[i] = make_pair(-h[i], i);
}
memset(vis, 0, sizeof(vis));
sort(p + 1, p + n + 1);//因为存的是负值,所以是从大到小排序
int sum = 0;//记录当前有多少个块
for(int i = 1; i <= n; i++) {
int x = p[i].second;
if(!vis[x - 1] && !vis[x + 1]) sum ++;//多一个块,因为两边都没被访问
else if(vis[x - 1] && vis[x + 1]) sum --;//合并两个块为一个,因为正好将两边连了起来,其他情况不会影响块的增加与减少
ans[i] = sum;//这里表示从第i个数据以下(数据是从大到小的)射击能够得到的块数
vis[x] = 1;
}
for(int i = 0; i < q; i++) {
int t;
scanf("%d", &t);//upper_bound返回一个非递减序列[first, last)中的第一个大于值val的位置。
int id = upper_bound(p + 1, p + n + 1, make_pair(-t, -1)) - p - 1;
printf("%d\n", ans[id]);
}
}
return 0;
}
HDU - 5200 - Trees (upper_bound)
原文地址:http://blog.csdn.net/u014355480/article/details/44878749