【问题描述】
数轴上有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】先不废话,先贴源代码:

 #include <stdio.h>
#include <stdlib.h> #define L 500005 int a[L]; int compare(const void *a, const void *b)
{
int *pa = (int*)a;
int *pb = (int*)b;
return (*pa) - (*pb);
} void swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
} int find(int begin, int end, int ac)
{
int mid, left = begin, right = end;
while (left <= right)
{
mid = left + ((right - left) >> );
if (a[mid] >= ac) right = mid - ;
else left = mid + ;
}
return left;
} int main()
{
int n, m, i;
scanf("%d %d\n", &n, &m); for (i = ; i < n; i++)
{
scanf("%d", &a[i]);
} //refer to http://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html
qsort(a, n, sizeof(int), compare); for (i = ; i < m; i++)
{
int l, r, ans, lf, rt;
scanf("%d %d", &l, &r); //make sure l <= r
if (l > r)
{
swap(l, r);
} rt = find(, n - , r);
lf = find(, n - , l);
ans = rt - lf;
if (a[rt] == r) ans++;
if (ans < ) ans = ; printf("%d\n", ans);
}
}

第一感觉都是这道题以前学的时候肯定做过,很简单,看到这个数据规模基本也就确定得用二分查找了。(反正看网上想先维护好线性数组再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)二分查找不要用递归形式。一是提高效率;二是防止堆栈溢出。

【Tsinghua OJ】范围查询(Range)问题的更多相关文章

  1. 【Tsinghua OJ】灯塔(LightHouse)问题

    描述 海上有许多灯塔,为过路船只照明.从平面上看,海域范围是[1, 10^8] × [1, 10^8] . (图一) 如图一所示,每个灯塔都配有一盏探照灯,照亮其东北.西南两个对顶的直角区域.探照灯的 ...

  2. 【Tsinghua OJ】祖玛(Zuma)问题

    描述 祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色.此后,你可以发射珠子到轨 道上并加入原有序列中.一旦有三个或更多同色的珠子变成相 ...

  3. 【Tsinghua OJ】隧道(Tunel)问题

    描述 现有一条单向单车道隧道,每一辆车从隧道的一端驶入,另一端驶出,不允许超车 该隧道对车辆的高度有一定限制,在任意时刻,管理员希望知道此时隧道中最高车辆的高度是多少 现在请你维护这条隧道的车辆进出记 ...

  4. 【Tsinghua OJ】多米诺骨牌(domino)问题

    (domino.c/cpp)[问题描述] 小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种.她觉 得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的.现在她有n个 ...

  5. 【Tsinghua OJ】循环移位(Cycle)

    Description Cycle shifting refers to following operation on the sting. Moving first letter to the en ...

  6. Tsinghua OJ Zuma

    Description Let's play the game Zuma! There are a sequence of beads on a track at the right beginnin ...

  7. MySQL查询分析器EXPLAIN或DESC

    转载:http://chenzehe.iteye.com/blog/1682081 MySQL可以通过EXPLAIN或DESC来查看并分析SQL语句的执行情况,如下需要计算2006年所有公司的销售额, ...

  8. 利用kibana插件对Elasticsearch查询

    利用kibana插件对Elasticsearch查询 Elasticsearch是功能非常强大的搜索引擎,使用它的目的就是为了快速的查询到需要的数据. 查询分类: 基本查询:使用Elasticsear ...

  9. 七、Django模型基础第二节——常用查询

    1 常用的模型字段类型 官方文档链接: https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types 常用的字段类型 模型字 ...

随机推荐

  1. [转载]Soap安全测试入门

    http://www.cnblogs.com/zerotest/p/4670902.html 在SoapUI4.0引入的安全测试特点使它非常容易为你来验证你的目标服务的功能性安全,就可以评估您的系统常 ...

  2. 190. Reverse Bits -- 按位反转

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  3. SQL Server 一列或多列重复数据的查询,删除

    业务需求 最近给公司做一个小工具,把某个数据库(数据源)的数据导进另一个数据(目标数据库).要求导入目标数据库的数据不能出现重复.但情况是数据源本身就有重复的数据.所以要先清除数据源数据. 于是就把关 ...

  4. WCF练习小程序总结

    1.什么是WCF 严格的说,WCF就是专门用于服务定制.发布与运行以及消息传递和处理的一组专门类的集合,也就是所谓的“类库”.这些类通过一定方式被组织起来,共同协 作,并为开发者提供了一个统一的编程模 ...

  5. cisco nat

    1.配置端口: int s0/0 ip nat outside                  ;s0/0为外部端口 int f0/0 ip nat inside                   ...

  6. 所思所想 关于asp.net界面业务分离

    1.体会:使用ASP.NET控件来做前段是有很大的局限性的 2.使用拼接HTML的方式来写代码虽然不符合模式,但是有很大的灵活性 3.如果使用拼接字符串的方式来生成前台的代码,使用NV的话完全可以实现 ...

  7. 如何实现301的跳转?当输入域名http://xxx.com的时候自动重定向到www上去

    答案:在服务器上操作,注意勾选和不勾选的区别,使用Fiddle进行观察,301和302之间的区别

  8. Eclipse中SVN的安装步骤(两种)和使用方法 [转]

    一.给Eclipse安装SVN,最常见的有两种方式:手动方式和使用安装向导方式.具体步骤如下: 方式一:手动安装 1.从官网下载site-1.6.9.zip文件,网址是:subclipse.tigri ...

  9. (转)虚拟机的桥接模式和NAT模式区别

    不管是虚拟机的桥接还是NAT都是占用实机网络的.只不过两种方式有些差异,在通过IP或者拨号连接限速的网络中,差异就很明显了     举个不太恰当但简单的例子,一个百兆的网卡你可以把它想象成一个100车 ...

  10. 使用ServerSocket创建TCP服务器端

    在两个通信实体没有建立虚拟链路之前,必须有一个通信实体先做出“主动姿态”,主动接受来自其他通信实体的连接请求. Java中能接受其它通信实体连接请求的类是ServerSocket,ServerSock ...