Tsinghua mooc 数据结构上 范围查询(Range) 快排+二分

先补一波mooc上数据结构的题,题面如下:
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

描述
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。

输入
第一行包括两个整数:点的总数n,查询的次数m。

第二行包含n个数,为各个点的坐标。

以下m行,各包含两个整数:查询区间的左、右边界a和b。

输出
对每次查询,输出落在闭区间[a, b]内点的个数。

样例
见英文题面

限制
0 ≤ n, m ≤ 5×105

对于每次查询的区间[a, b],都有a ≤ b

各点的坐标互异

各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数

时间:2 sec

内存:256 MB

直接查找速度很慢,只能过不到一半的数据。所以用快排+二分法来快速查找,顺便学了波快排,就是选中一个元素,将比大的元素放在它右边,比它小的元素放它左边,以此达到二分的效果,然后再递归。
上代码:

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

const int SZ = 1<<20;
struct fastio{
    char inbuf[SZ];
    char outbuf[SZ];
    fastio(){
        setvbuf(stdin,inbuf,_IOFBF,SZ);
        setvbuf(stdout,outbuf,_IOFBF,SZ);
    }
}io;

const int maxn=5e5+20;
int ss[maxn];
int m,n,ml,mr;

void quickSort(int l,int r)
{
    if(l<r)
    {
    int i=l,j=r,x=ss[i];
    while(i<j)
    {
        while(i<j&&ss[j]>=x)
            j--;
        if(i<j)ss[i++]=ss[j];
        while(i<j&&ss[i]<x)
            i++;
        if(i<j)ss[j--]=ss[i];
    }
    ss[i]=x;
    quickSort(l,i);
    quickSort(i+1,r);
    }
}

int binary (int t1,int t2)
{
    long long int tl,tr;
    long long int l=0,r=n-1,mid;
    if(ss[0]>=t1)tl=0;
    else {
        while(r-l>1)
        {
            mid=(l+r)/2;
            if(ss[mid]<t1)l=mid;
            else r=mid;
        }
        tl=r;
    }
    l=0,r=n-1;
    if(ss[n-1]<=t2)tr=n-1;
    else {
        while(r-l>1)
        {
            mid=(l+r)/2;
            if(ss[mid]<t2)l=mid;
            else r=mid;
        }
        tr=l;
    }
    if(tl>0&&ss[tl-1]>=t1)tl--;
    if(tr<n-1&&ss[tr+1]<=t2)tr++;
    if(tl>tr)return 0;
    else return tr-tl+1;
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&ss[i]);
    }
    quickSort(0,n-1);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&ml,&mr);
        if(mr<ss[0]||ml>ss[n-1])printf("0\n");
        else {int bb=binary(ml,mr);printf("%d\n",bb);}
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wbl1970353515/article/details/82562084