zoukankan      html  css  js  c++  java
  • 范围查询(Range)

    范围查询(Range)


    Descriptioin

    Let S be a set of n integral points on the x-axis. For each given interval [a, b], you are asked to count the points lying inside.

    Input

    The first line contains two integers: n (size of S) and m (the number of queries).

    The second line enumerates all the n points in S.

    Each of the following m lines consists of two integers a and b and defines an query interval [a, b].

    Output

    The number of points in S lying inside each of the m query intervals.

    Example

    Input

    5 2
    1 3 7 9 11
    4 6
    7 12
    

    Output

    0
    3
    

    Restrictions

    0 <= n, m <= 5 * 10^5

    For each query interval [a, b], it is guaranteed that a <= b.

    Points in S are distinct from each other.

    Coordinates of each point as well as the query interval boundaries a and b are non-negative integers not greater than 10^7.

    Time: 2 sec

    Memory: 256 MB

    解法一:

    1. 原理与要点: 因为坐标的范围比较小,只有1e7,且均为非负数,就很容易想到用前缀和来解决这个问题。

    求前缀和((a_i = sum_{j=0}^{i}b_j)(b_j)存储坐标为j的点的个数,(a_i)存储区间[0,i]内点的个数),对每次询问的(l,r)输出 $ a_r-a_{l-1}$

    1. 遇到的问题:
    2. 时间和空间复杂度:求前缀和时间复杂度(O(1e7)),每次查询复杂度(O(1))。理论复杂度比排序+二分的解法更优。空间复杂度(O(1e7))
    3. 特别或创新: 对于这道题的数据量来说,前缀和更快,编程更简单。
    #include "iostream"
    #include "cstdio"
    
    using namespace std;
    const int maxn = 1e7+ 100;
    int a[maxn];
    
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        int x;
        for (int i = 0; i < n; i++) {
            scanf("%d", &x);
            a[x]++;
        }
        for (int i = 1; i < maxn - 1; i++) {
            a[i] += a[i - 1];
        }
        int l, r;
        while (m--) {
            scanf("%d %d", &l, &r);
            if (l != 0)
                printf("%d
    ", a[r] - a[l - 1]);
            else
                printf("%d
    ", a[r]);
        }
        return 0;
    }
    

    解法二:

    1. 原理与要点:将所有的点存到一个数组里然后排序,每次询问时二分查找到左端点和右端点,相减得到查询结果
    2. 遇到的问题:
    3. 时间和空间复杂度:时间复杂度(O(nlogn)),空间复杂度(O(n))
    4. 特别或创新:
    #include "cstdio"
    #include "stdlib.h"
    #include "iostream"
    
    using namespace std;
    const int maxn = 5e5 + 100;
    const int inf = 0x3f3f3f3f;
    const int SZ = 1 << 20;  //快速io
    struct fastio {
        char inbuf[SZ];
        char outbuf[SZ];
    
        fastio() {
            setvbuf(stdin, inbuf, _IOFBF, SZ);
            setvbuf(stdout, outbuf, _IOFBF, SZ);
        }
    } io;
    
    int cmp(const void *a, const void *b) {
        return *(int *) a - *(int *) b;
    }
    
    int a[maxn];
    
    int main() {
        int n, q;
        scanf("%d %d", &n, &q);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        a[0] = -inf;
        a[n + 1] = inf;
        qsort(a, n + 1, sizeof(a[0]), cmp);
        int x, y;
        int from, to;
        int l, r, mid;
        while (q--) {
            scanf("%d %d", &x, &y);
            l = 0, r = n + 1;
            while (l < r) {
                mid = (l + r + 1) >> 1;
                if (a[mid] >= x) r = mid - 1;
                else l = mid;
            }
            from = l;
            l = 0, r = n + 1;
            while (l < r) {
                mid = (l + r) >> 1;
                if (a[mid] <= y) l = mid + 1;
                else r = mid;
            }
            to = l;
            printf("%d
    ", to - from - 1);
        }
        return 0;
    }
    
  • 相关阅读:
    Ubuntu下设置静态网址
    Ubuntu下qemu环境搭建vexpress开发平台
    Ubuntu管理员密码设置
    学习MFC创建界面
    opencv3.0之后IPLimage转换成MAT的问题
    C++的ofstream与ifstream使用
    PCA主成分分析
    pycharm但多行注释快捷键
    fiddler不同代理模式的区别
    Python 常用模块大全(整理)
  • 原文地址:https://www.cnblogs.com/albert-biu/p/11542093.html
Copyright © 2011-2022 走看看