TsingHua OJ 上不能使用<algorithm>头文件,因此需要手写快排(刚开始写的时候自己就出了很多问题....),另外本题需要在给横坐标排序后,需要记录纵坐标的顺序对的数量,因此,最快的算法貌似只有归并排序或者树状数组的方法进行顺序对的查找和记录了,时间度为O(nlogn),另外此前需要一次对横坐标的排序,这里用快排。

灯塔(LightHouse)


描述

海上有许多灯塔,为过路船只照明。

如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。

若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。

现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。

输入

共n+1行。

第1行为1个整数n,表示灯塔的总数。

第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。

输出

1个整数,表示可照亮彼此的灯塔对的数量。

Example

Input

3
2 2
4 3
5 1

Output

1

限制

对于90%的测例:1 ≤ n ≤ 3×105

对于95%的测例:1 ≤ n ≤ 106

全部测例:1 ≤ n ≤ 4×106

灯塔的坐标x, y是整数,且不同灯塔的x, y坐标均互异

1 ≤ x, y ≤ 10^8

时间:2 sec

内存:256 MB

提示

注意机器中整型变量的范围,C/C++中的int类型通常被编译成32位整数,其范围为[-231, 231 - 1],不一定足够容纳本题的输出。


解题思路:

  乱序的坐标对我们解题是没有帮助的,因此我们首先应该想到对横坐标(纵坐标)做一次排序,然后考虑纵坐标(横坐标)。

在这里我先对横坐标进行排序,然后从小到大对纵坐标的要求进行归纳,我们可以发现:如果存在两个灯塔A(x1,y1),B(x2,y2),那么x1<x2时,当且仅当y1<y2时,A B两灯塔才能相互beacon(照亮),因此,这道题可以转化为当横坐标顺序确定时,去记录纵坐标的顺序对数量。

  例如A(1,2),B(2,4),C(3,5),那么显然ABC中任两灯塔间可以相互beacon,其对数就是三对。

  ——我们用顺序对来描述就是:A B C顺序摆放,其中AB,AC,BC的纵坐标(<2,4>,<2,5>,<4,5>)各为一个顺序对,因此有三对灯塔可以相互beacon,这与我们的分析是一致的。

时间度分析:

  那么在分析完这道题目后,我们就需要做两件事情,第一件事就是对横坐标进行一次排序,第二件事就是利用某种算法计算出横坐标排序后,纵坐标的顺序对的数量。

  在题目中给出 全部测例:1 ≤ n ≤ 4×10这个数据量是很大的,因此我们必须要用快排对横坐标排序,时间度认为是O(nlogn),第二件事中,联系到逆序对的记录,我们可以用到的最快算法有归并排序和树状数组,这里我们试用归并排序进行顺序对记录,时间度也认为是O(nlogn)。

  以下是实现Code:

 #include<stdio.h>

 #define MAX 4000005
long ans; struct Light{
int x, y;
}l[MAX]; int tmp[MAX]; /*快排*/
void quickSort(int low, int high)
{
int i = low;
int j = high;
Light x = l[low]; //设置一个基准点
do{
while (l[i].x < x.x) i++; //Let l[i].x >= x
while (l[j].x > x.x) j--; //Let l[j].x <= x
if(i <= j){ //SWAP
Light t = l[i];
l[i] = l[j];
l[j] = t;
i++; j--;
}
} while (i <= j); //使得p两侧满足 左<=p,右>=p
if(i < high) quickSort(i, high);
if(j > low ) quickSort(low, j);
} void merge(int low, int mid, int high)
{
int s = low, t = mid + , k = low;
while (s <= mid && t <= high){
if (l[s].y < l[t].y){
ans += high - t + ; //顺序对-右侧未放入的date数量
tmp[k++] = l[s++].y;
}
else tmp[k++] = l[t++].y;
}
if (s == mid + ) while (k <= high) tmp[k++] = l[t++].y;
else while (k <= high) tmp[k++] = l[s++].y;
//COPY
for (int i = low; i <= high; i++) l[i].y = tmp[i];
} /*归并排序*/
void mergeSort(int low, int high)
{
if (low < high){
int mid = (low + high) / ;
mergeSort(low, mid);
mergeSort(mid + , high);
merge(low, mid, high);
}
} int main()
{
int n;
scanf("%d", &n);
for (int i = ; i < n; i++)
scanf("%d%d", &l[i].x, &l[i].y);
quickSort(, n - );//横坐标快排
mergeSort(, n - );//纵坐标归并排序并记录顺序对 printf("%ld\n", ans); return ;
}

小墨- -原创

  尽管如此,但是我们依然只能A掉95%的样例,说明我们的算法依然不够快,依然要进行优化,那么在这里效果最显著的方法

  一个就是改归并排序树状数组可能相对要更快一些,另一个就是优化手写的快速排序算法,可以采用生成随机数或者采用三数取中等等优化方法使得我们手写的快排更趋近稳定,但是由于时间原因,小编没有尝试下去。

ACM/ICPC 之 快排+归并排序-记录顺序对(TSH OJ-LightHouse(灯塔))的更多相关文章

  1. 2017 ACM/ICPC Asia Regional Shenyang Online 记录

    这场比赛全程心态爆炸…… 开场脑子秀逗签到题WA了一发.之后0贡献. 前期状态全无 H题想复杂了,写了好久样例过不去. 然后这题还是队友过的…… 后期心态炸裂,A题后缀数组理解不深,无法特判k = 1 ...

  2. 2017 ACM/ICPC Asia Regional Guangxi Online 记录

    题目链接  Guangxi 感觉这场比赛完全是读题场啊…… 比赛过程中丢失了一波进度,最后想开题的时候已经来不及了…… Problem A 按题意模拟……按照那个矩阵算就可以了 #include &l ...

  3. 2017 ACM/ICPC Asia Regional Beijing Online 记录

    题目链接  Beijing

  4. 2017 ACM/ICPC Asia Regional Xian Online 记录

    题目链接  Xian

  5. 2017 ACM/ICPC Asia Regional Qingdao Online 记录

    题目链接  Qingdao Problem C AC自动机还不会,暂时暴力水过. #include <bits/stdc++.h> using namespace std; #define ...

  6. 2017 ACM/ICPC Asia Regional Urumuqi Online 记录

    比赛题目链接  Urumuqi

  7. ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))

    这一题是TsingHua OJ上的一道题目,学堂在线的一位数据结构老师的题目(原创),所以我直接把题目先贴下来了,这道题对复习双向链表很有帮助,而且也对数据结构中List,也就是对列表的回顾也是很有帮 ...

  8. ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))

    一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...

  9. Java排序算法分析与实现:快排、冒泡排序、选择排序、插入排序、归并排序(二)

    一.概述: 上篇博客介绍了常见简单算法:冒泡排序.选择排序和插入排序.本文介绍高级排序算法:快速排序和归并排序.在开始介绍算法之前,首先介绍高级算法所需要的基础知识:划分.递归,并顺带介绍二分查找算法 ...

随机推荐

  1. vim黏贴代码格式混乱的解决方法

    from:http://blog.csdn.net/commshare/article/details/6215088 感谢牛人的文章.解决了我在vim使用中,很头疼的问题. 在vim新建文件的时候, ...

  2. css使 同一行内的 文字和图片 垂直居中对齐?

    设置父容器, 使 父容器 div 下的所有元素 都 垂直对齐: father-container *{ vertical-align:middle 找回密码

  3. Job中织梦标签的调用

    织梦CMS是一个好东东, 可以让一个网站更好维护和管理, 唯一让我感到忧桑的就是经常在搭后台的时候记不住那些标签,,无奈只能去看手册,有相同的案例直接COPY过来,直接用就OK~~~其实CMS这个东西 ...

  4. 基础知识系列☞MSSQL→约束

    遇到一个数据库设计很渣的系统··· 本来一个约束就能解决的问题·以前建库的时候也不设计好···

  5. HDOJ 3593 The most powerful force

    树形DP / 泛化物品的背包...可以去看09年徐持衡论文<浅谈几类背包问题> The most powerful force Time Limit: 16000/8000 MS (Jav ...

  6. java 在接口里函数不能重载?

    项目里使用hession远程调用serviceRemote接口,而serviceRemote接口里有两个save方法,参数分别是CpCredential对象和List,但运行发现会报莫名其妙的错. 后 ...

  7. oracle数据库表空间扩容方法

    1. 先查询表空间在物理磁盘上存放的位置,注意使用sysdba的账号登陆. SELECT tablespace_name, file_id, file_name, ), ) total_space F ...

  8. loadrunner 学习笔记--AJAX(转)

    用loadrunner测试WEB程序的时候总是会碰到AJAX或者ActiveX实现的功能,而通常这些功能会包含很多客户端函数(一般为JavaScript).我们该如何处理?如果从功能实现的角度去考虑这 ...

  9. WebSocket帧数据 解码/转码

    数据从浏览器通过websocket发送给服务器的数据,是原始的帧数据,默认是被掩码处理过的,所以需要对其利用掩码进行解码. 从服务器发送给浏览器的数据是默认没有掩码处理的,只要符合一定结构就可以了.具 ...

  10. HDU 5384 字典树、AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...