清华OJ-范围查询

题目链接:https://dsa.cs.tsinghua.edu.cn/oj/course.shtml?courseid=58

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

————————————————————————————————————————————————————————————————————————————————————

实在是花了不少时间来做,仍然没有过!

以下是得50分的代码

//范围查询(Range)
#include <iostream>
#include <malloc.h>
using namespace std;
int n = 0;
int query(int q[],int a,int b);

int main(){
    int pn , qn , *p , x , y ;  //pn是点的个数,qn是查询的次数
    int curpoint = 0;
    cin>>pn>>qn;
    n = pn;
    p=(int*) malloc (sizeof(int) * pn);
    for(int i = 0 ; i < pn; i++)
    {    
        cin>>curpoint;
        p[i] = curpoint;
    }
    
    for(int j = 1; j <= qn; j++)
    {
        cin>>x>>y;
        cout<<query(p,x,y)<<endl;
    }
    free(p);
    return 0;
}
 
int query(int q[],int a,int b){ 
//查询在范围内的点,返回点的个数
    int count = 0 , i , j ;
    for(int i = 0 ; i <= n ; i++)
        if(q[i] >= a && q[i] <= b) count++;
    
    return count;
}

今天修改并测试过了二分查询,但提交后判分只得15分:

 

//范围查询(Range)
#include <iostream>
#include <malloc.h>
using namespace std;
int n = 0;
int query(int q[],int a,int b); 
int BinerySearch(int *q,int x,int y,int v);  //二分查找
int main(){
    int pn , qn , *p , x , y;  //pn是点的个数,qn是查询的次数
    int curpoint = 0;
    cin>>pn>>qn;
    n = pn;
    p=(int*) malloc (sizeof(int) * pn);
    for(int i = 0 ; i < pn; i++)//输入点的数值 
    {    
        cin>>curpoint;
        p[i] = curpoint;
    }
    //范围的查询
    for(int j = 1; j <= qn; j++)
    {
        cin>>x>>y;
        cout<<query(p,x,y)<<endl;
    }
    free(p);
    return 0;
}

int BinerySearch(int *q,int lo,int hi,int v){
    //二分查找 用于查询v这个数值在数组中应该是什么位置 
    if (v >= q[hi]) return hi;
    if (v <= q[lo]) return lo;
    while (lo <= hi)
    {
        int mid = lo + (hi - lo)/2;
        if ( q[mid] == v || (v > q[mid] && v < q[mid+1])) return mid;
        else if (q[mid] > v) hi = mid;
        else if(v > q[mid]) lo = mid + 1;
        
    }
    return -1;
}

int query(int q[],int a,int b){ 
//查询在范围内的点,返回点的个数
    int count = 0 , i , j ;
    i = BinerySearch(q,0,n-1,a);
    j = BinerySearch(q,0,n-1,b);
    for(i; i <= j ; i++)
        if(q[i] >= a && q[i] <= b) count++;
    return count;
}

看来还需要提升自己,多听邓老师的课,提高算法的认识。

posted @ 2021-10-20 10:23  蒋弢  阅读(296)  评论(0编辑  收藏  举报