FJUT寒假第一周作业浮点数查寻题解

二分强化——浮点数序列查询

TimeLimit:4000MS  MemoryLimit:128MB
64-bit integer IO format:%I64d
Problem Description

已知在二维空间中有n个点,p0,p1……pn-1

已按照x为第一优先级,y为第二优先级从大到小排好序;

即若 pi<pj

则pi.x<pj.x,或者pi.x==pj.x&&pi.y<pj.y

Input

只有一组数据
第一行是两个整数n,m分别代表点的个数和查询次数
接下来n行,每行有二个带三位小数的浮点数x,y代表一个点的坐标
再接下来m行,每行的有4个数字x1,y1,x2,y2代表p1,p2且p1>=p2

其中n,m<=100000;

任意0<=x,y<10^6;

Output

输出n个点所有小于等于p1且大于等于p2的点的下标之和

SampleInput
6 4
125.689 125.689
125.689 125.688
125.688 125.689
125.688 125.689
125.688 125.688
125.688 125.688
125.688 125.688 125.688 125.688
125.688 125.689 125.688 125.688
125.689 125.689 125.688 125.689
125.688 125.689 125.688 125.689
SampleOutput
9
14
6
5
明显是二分,没啥好解释的。
输出:n个点所有小于等于p1且大于等于p2的点的下标之和因为是包括等于,
所以我们可以用二分直接找出和点(x1,y1)相等的最小下标(数是从大到小,所以是最小下标)并记录,
接着在从(i-1)~n中找出和点(x2,y2)相等的最大下标
最小下标和,很容易看出是一个等差数列求和
这题唯一的坑:本身数据是不超过int,但是下标和为爆int 所以要用long long
下面附上部分核心代码:
        x=-1;//x为下界
        s=n;//s为上界
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        while(x+1<s)
        {
            z=(s+x)/2;//
            if(a[z]>x1||(a[z]==x1&&b[z]>y1))//第一优先级大于或者第一相等 第二大于
                x=z;
            else
                s=z;
        }
        i=s;//i用来存点(x1,y1)相等的最小下标
        x=s-1;//缩小下界范围减时间,因为x1y1 大于x2y2,所以下界最小为s-1 
        s=n;//上界不变
        while(x+1<s)
        {
            z=(s+x)/2;
            if(a[z]>e||(a[z]==x2&&b[z]>=y2))
                x=z;
            else
                s=z;
        }
        s=s-1;//上面二分求出的是小于(x2,y2)的最小下标,减1后就是相等的最大下标
        printf("%lld\n",(i+s)*(s-i+1)/2);//s-i+1是i~s的长度

 



posted @ 2017-12-30 15:31  fjut-Hang  阅读(228)  评论(0编辑  收藏  举报