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;
//}
//
//
时间: 2024-07-29 07:03:57

lightoj-1088 - Points in Segments(二分法)的相关文章

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 segme

Lightoj 1088 - Points in Segments 【二分】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1088 题意: 有一维的n个点和q条线段.询问每条线段上的点有多少个: 思路:寻找这些点中对于每条线段的上下界即可. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include

LightOJ 1088 - Points in Segments 二分

http://www.lightoj.com/volume_showproblem.php?problem=1088 题意:给出N个点,Q个查询,问在区间内的点数有多少个. 思路:直接在线二分,注意边界问题 /** @Date : 2016-12-17-19.03 * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : */ #include<bits/stdc++.h> #defin

LightOJ 1089 - Points in Segments (II) 线段树区间修改+离散化

http://www.lightoj.com/volume_showproblem.php?problem=1089 题意:给出许多区间,查询某个点所在的区间个数 思路:线段树,由于给出的是区间,查询的是点,考虑将其离线并离散化,普通线段树即可. /** @Date : 2016-12-17-20.49 * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : */ #include<bi

Codeforces Round #245 (Div. 2) A - Points and Segments (easy)

水到家了 #include <iostream> #include <vector> #include <algorithm> using namespace std; struct Point{ int index, pos; Point(int index_ = 0, int pos_ = 0){ index = index_; pos = pos_; } bool operator < (const Point& a) const{ return p

Codeforces 430A Points and Segments (easy)

题意:让你染色点,要求在给出的区间内|红色个数-蓝色个数|<=1 思路:排序后依次交替染色就能达到效果 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <vector> using namespace std; const int MAXN = 110; int arr[MAXN]; int n,m,x,y; int

【CF429E】Points and Segments 欧拉回路

[CF429E]Points and Segments 题意:给你数轴上的n条线段$[l_i,r_i]$,你要给每条线段确定一个权值+1/-1,使得:对于数轴上的任一个点,所有包含它的线段的权值和只能是+1,-1或0. $n\le 10^5$ 题解:首先,我们用扫描线,整个数轴被分成若干个小区间.对于一个小区间,如果有偶数条线段包含它,则它的权值只能是0,否则可以是+1/-1.我们可以在所有权值为+1/-1的小区间处人为的增加一条线段,这样的话我们只需要让所有小区间权值都是0就行了. 嗯...每

ACM ——Points in Segments

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 t

CodeForces A. Points in Segments

http://codeforces.com/contest/1015/problem/A You are given a set of nn segments on the axis OxOx, each segment has integer endpoints between 11 and mm inclusive. Segments may intersect, overlap or even coincide with each other. Each segment is charac