lightoj-1088 - Points in Segments(二分法)

Posted FireCool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lightoj-1088 - Points in Segments(二分法)相关的知识,希望对你有一定的参考价值。

1088 - Points in Segments
PDF (English) Statistics Forum
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.

 

题目大意:给出一些在数轴上的点, 然后给出一段区间,问这段区间上有几个点。

解题思路:写这题的时候看到题目segment 有点先入为主,以为用线段树写,然后就用了分块的方法写,然后MLT ,GG了

这题就是二分查找出对应两端的下标,相减就可以了。

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

const int N = 100010;
int T,n,q,under1,under2;
int a[N]; 


//寻找mid 使得a[mid]<=value<a[mid+1] 
int binaryS(int value){
    
    int l=1,r=n;
    while(l<=r){
        int mid = (l+r)>>1;
        
        if(a[mid]>value) r = mid-1;
        else if(a[mid+1]>value) return mid;
        else l = mid+1;
    }
    return 0;
} 


int main(){
    
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        
        scanf("%d%d",&n,&q);
        
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        printf("Case %d:\n",t);
        for(int i=0;i<q;i++){
            scanf("%d%d",&under1,&under2);
            if(under1<a[1]) under1 = 0;
            else{    //因为寻找的是a[mid]<=value<a[mid],所以当a[mid]==under1时应该-1? 
                int temp = binaryS(under1);
                if(a[temp]==under1)  under1 = temp-1;
                else under1 = temp;
            }
            
            if(under2>=a[n]) under2 = n;
            else under2 = binaryS(under2);
            printf("%d\n",under2-under1);
        }
        
    }
    
    return 0;
}


//分块的求法 
//const int ss = sqrt(1e8);
//int Size[10010];
//int a[100000010];
//
//int main(){
//    
//    int T,n,q,val,size,under1,under2,s1,s2,sum;
//    
//    scanf("%d",&T);
//    memset(Size,0,sizeof(Size));
//    memset(a,0,sizeof(a));
//    for(int t=1;t<=T;t++){
//        scanf("%d%d",&n,&q);
//        for(int i=0;i<n;i++){
//            scanf("%d",&val);
//            a[val] = 1;
//            Size[int(val/ss)] += 1;
//        }
//        printf("Case %d:\n",t);
//        for(int i=0;i<q;i++){
//            sum  = 0;
//            scanf("%d%d",&under1,&under2);
//            s1 = under1/ss;
//            s2 = under2/ss;
//            for(int j = under1;j<=min(under2,(s1+1)*ss-1);j++) sum+=a[j];
//            for(int j = s1+1;j<s2;j++) sum += Size[j];
//            
//            if(s1!=s2){
//                for(int j=s2*ss;j<=under2;j++) sum+=a[j];
//            }
//            printf("%d\n",sum);
//        }
//        
//    }
//    
//    return 0;
//}
//
//

 

以上是关于lightoj-1088 - Points in Segments(二分法)的主要内容,如果未能解决你的问题,请参考以下文章

Lightoj 1088 - Points in Segments 二分

Static Probe Points in GDB

ACM ——Points in Segments

CodeForces A. Points in Segments

Division and Recursion--find the nearest points in two dimension

Points in Rectangle (II) LightOJ - 1267