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

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

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

即若 pi<pj

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

 

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

其中n,m<=100000;

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

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

输入:

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

 

输出:
9
14
6
5

思路:二分法

 1 #include<stdio.h>
 2 double a[100005],b[100005];
 3 int main()
 4 {
 5     long long n,m,v,s,i,mid;
 6     double z,k,x,y;
 7     scanf("%lld%lld",&n,&m);
 8     for(i=0; i<n; i++)
 9     {
10         scanf("%lf %lf",&a[i],&b[i]);///输入n对元素
11     }
12     while(m--)
13     {
14         scanf("%lf %lf %lf %lf",&z,&k,&x,&y);///输入判断的元素
15         int up=n,down=-1;
16         while(down+1<up)
17         {
18             mid=(down+up)/2;
19             if(a[mid]>z||(a[mid]==z&&b[mid]>k))///优先级的比较
20                 down=mid;
21             else
22                 up=mid;
23         }
24         v=up;///二分找左边的界 v代表那个地方的坐标
25         up=n,down=v-1;///因为从大到小 所以从v-1开始继续找就好了
26         while(down+1<up)
27         {
28             mid=(down+up)/2;
29             if(a[mid]>x||(a[mid]==x&&b[mid]>=y))
30                 down=mid;
31             else
32                 up=mid;
33         }
34         s=down;///s代表那个地方的坐标
35         v--;
36         printf("%lld\n",(s*s+s-v*v-v)/2);///等差数列的和
37     } ///用lld是因为s*s可能会爆int (坑)
38 }

 

posted @ 2017-12-28 18:57  star_fish  阅读(254)  评论(0编辑  收藏  举报