首页 > 代码库 > LightOJ 1088 Points in Segments 二分查找

LightOJ 1088 Points in Segments 二分查找

1088 - Points in Segments
PDF (English)StatisticsForum
Time Limit: 2 second(s)Memory Limit: 32 MB

Given n points (1 dimensional) and q segments, you have to find the number of points that lie in each of the segments. A point pi will lie in a segment A B if A ≤ pi ≤ B.

For example if the points are 1, 4, 6, 8, 10. And the segment is 0 to 5. Then there are 2 points that lie in the segment.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

Each case starts with a line containing two integers n (1 ≤ n ≤ 105) and q (1 ≤ q ≤ 50000). The next line contains n space separated integers denoting the points in ascending order. All the integers are distinct and each of them range in [0, 108].

Each of the next q lines contains two integers Ak Bk (0 ≤ Ak ≤ Bk ≤ 108) denoting a segment.

Output

For each case, print the case number in a single line. Then for each segment, print the number of points that lie in that segment.

Sample Input

Output for Sample Input

1

5 3

1 4 6 8 10

0 5

6 10

7 100000

Case 1:

2

3

2

Note

Dataset is huge, use faster I/O methods.


题解

这个不是二分答案的那种题了,是比较正常的那种集合区间中的那种元素查找的二分题目了。题意很简单,给n个有序的数,这些数分布在一个坐标轴上。给q次查找,询问在区间[x, y](这里的符号和代码的保持一致)中有多少个数据。

解法就是自己写一个二分函数upper_bound和lower_bound,然后直接计算区间即可。

代码示例

/****
	*@author    Shen
	*@title     LightOj 1088
	*/

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

const int maxN = 100005;
int a[maxN];
int t, tt;
int n, q, x, y;

int Bsearch_lower_bound(int x)
{
    int l = 0, r = n - 1, mid = 0;
    while (l <= r)
    {
        mid = (l + r) >> 1;
        if (a[mid] < x) l = mid + 1;
        else r = mid - 1;
    }
    return l;
}

int Bsearch_upper_bound(int x)
{
    int l = 0, r = n - 1, mid = 0;
    while (l <= r)
    {
        mid = (l + r) >> 1;
        if (a[mid] <= x) l = mid + 1;
        else r = mid - 1;
    }
    return l;
}

void solve()
{
    scanf("%d%d", &n, &q);
    printf("Case %d:\n", ++tt);
    for (int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    for (int i = 0; i < q; i++)
    {
        scanf("%d%d", &x, &y);
        int l = Bsearch_lower_bound(x);
        int r = Bsearch_upper_bound(y);
        printf("%d\n", r - l);
    }
}

int main()
{
    scanf("%d", &t);
    while (t--) solve();
    return 0;
}