二分强化——浮点数序列查询
已知在二维空间中有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 }