【问题描述】
数轴上有n个点,对于任一闭区间 [a, b],试计算落在其内的点数。
【输入】
第一行包括两个整数:点的总数n,查询的次数m。
第二行包含n个数,为各个点的坐标。
以下m行,各包含两个整数:查询区间的左、右边界a和b。
【输出】
对每次查询,输出落在闭区间[a, b]内点的个数。
【输入样例】
5 2
1 3 7 9 11
4 6
7 12
【输出样例】
0
3
【限制】
0 ≤ n, m ≤ 5×105
对于次查询的区间[a, b],都有a ≤ b
各点的坐标互异
各点的坐标、查询区间的边界a、b,均为不超过10^7的非负整数
时间:2s,内存:256MB
【solution】先不废话,先贴源代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define L 500005 5 6 int a[L]; 7 8 int compare(const void *a, const void *b) 9 { 10 int *pa = (int*)a; 11 int *pb = (int*)b; 12 return (*pa) - (*pb); 13 } 14 15 void swap(int &a, int &b) 16 { 17 int temp; 18 temp = a; 19 a = b; 20 b = temp; 21 } 22 23 int find(int begin, int end, int ac) 24 { 25 int mid, left = begin, right = end; 26 while (left <= right) 27 { 28 mid = left + ((right - left) >> 1); 29 if (a[mid] >= ac) right = mid - 1; 30 else left = mid + 1; 31 } 32 return left; 33 } 34 35 36 int main() 37 { 38 int n, m, i; 39 scanf("%d %d\n", &n, &m); 40 41 for (i = 0; i < n; i++) 42 { 43 scanf("%d", &a[i]); 44 } 45 46 //refer to http://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html 47 qsort(a, n, sizeof(int), compare); 48 49 for (i = 0; i < m; i++) 50 { 51 int l, r, ans, lf, rt; 52 scanf("%d %d", &l, &r); 53 54 //make sure l <= r 55 if (l > r) 56 { 57 swap(l, r); 58 } 59 60 rt = find(0, n - 1, r); 61 lf = find(0, n - 1, l); 62 ans = rt - lf; 63 if (a[rt] == r) ans++; 64 if (ans < 0) ans = 0; 65 66 printf("%d\n", ans); 67 } 68 }
第一感觉都是这道题以前学的时候肯定做过,很简单,看到这个数据规模基本也就确定得用二分查找了。(反正看网上想先维护好线性数组再O(1)的查找是没混过去的)
实际上,二分查找并没有看起来那么简单,尤其是具体写起来的时候,有很多细节与临界点的处理都得根据实际情况仔细斟酌。
结合上述源代码,有几点值得注意的地方:
1)qsort的用法,参考了:http://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html。 Tsinghua OJ 不支持 algorithm 库。
2)倒数第三行代码(if (a[rt] == r) ans++;
)实际上就是二分查找结合具体情况对答案的调整。不妨分上界和下界等于或者不等于a数组中的值分情况讨论,即可明白这一行的涵义。这也跟二分查找几个细节的处理相统一。
3)二分查找函数中这一行:mid = left + ((right - left) >> 1);
。一方面,位运算提高运算效率;另一方面,不直接用 (left + right) >> 1
防止计算过程中数字越界,进而导致数组下标越界。
4)二分查找不要用递归形式。一是提高效率;二是防止堆栈溢出。
[ by Maples7 ]
[ Copyright @Maples7,转载请注明出处。 ]
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步