灯塔 (数据结构)

Posted ido-911

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了灯塔 (数据结构)相关的知识,希望对你有一定的参考价值。

灯塔(LightHouse)


Description

As shown in the following figure, If another lighthouse is in gray area, they can beacon each other.

技术图片

For example, in following figure, (B, R) is a pair of lighthouse which can beacon each other, while (B, G), (R, G) are NOT.

技术图片

Input

1st line: N

2nd ~ (N + 1)th line: each line is X Y, means a lighthouse is on the point (X, Y).

Output

How many pairs of lighthourses can beacon each other

( For every lighthouses, X coordinates won‘t be the same , Y coordinates won‘t be the same )

Example

Input

3
2 2
4 3
5 1

Output

1

Restrictions

For 90% test cases: 1 <= n <= 3 * 105

For 95% test cases: 1 <= n <= 106

For all test cases: 1 <= n <= 4 * 106

For every lighthouses, X coordinates won‘t be the same , Y coordinates won‘t be the same.

1 <= x, y <= 10^8

Time: 2 sec

Memory: 256 MB

Hints

The range of int is usually [-231, 231 - 1], it may be too small.

 

解题思路:将灯塔按照x轴由大到小排序,即将问题转化为求y的逆序对的个数。求解逆序对可以利用归并排序的思路实现。

如下图:在某次归并的时候,左右两个数组已经排好顺序,如果遇到a[i] > a[j],则,a[j] 与a[i] 到a[n]的所有元素均构成逆序对。

技术图片

 

 

在归并排序的时候顺便统计一下逆序对的个数。

 注意,要统计的逆序对个数可能很大。

代码如下

 

技术图片
#include<cstdio>
#include<cstring>
#define MAXN 4000005
#define ll long long 
using namespace std;

struct node{
    ll x;
    ll y;
} tower[MAXN];
ll des[MAXN];
struct node des1[MAXN];
int N;
ll num;
void merg(int l, int mid, int r)
{
    int i, j;
    int k;
    i = l;
    k = l;
    j = mid + 1;
    while(i <= mid && j <= r){
        if(tower[i].x < tower[j].x){
            des1[k].x = tower[i].x;
            des1[k++].y = tower[i++].y;
        }
        else{
            des1[k].x = tower[j].x;
            des1[k++].y = tower[j++].y;
        }
    }
    while(i <= mid){
        des1[k].x = tower[i].x;
        des1[k++].y = tower[i++].y;
    }
    while(j <= r){
        des1[k].x = tower[j].x;
        des1[k++].y = tower[j++].y;
    }

    for (i = l; i <= r; i++){
        tower[i].x = des1[i].x;
        tower[i].y = des1[i].y;
    }
}
void msort(int l, int r){
    if(l >= r - 1)
    {
        if(tower[l].x > tower[r].x){
            int x, y;
            x = tower[l].x;
            y = tower[l].y;
            tower[l].x = tower[r].x;
            tower[l].y = tower[r].y;
            tower[r].x = x;
            tower[r].y = y;
        }
        return;
    }
    int mid = (l + r) >> 1;
    msort(l, mid);
    msort(mid + 1, r);
    merg(l, mid, r);
}

void merge1(int l, int mid, int r)
{
    int i, j;
    ll cnt = 0;
    int k = l;
    i = l;
    j = mid + 1;
    while(i <= mid && j <= r){
        if(tower[i].y < tower[j].y){
            des[k++] = tower[i++].y;
            cnt += r - j + 1;
        }
        else{
            des[k++] = tower[j++].y;
        }
    }
    while(i <= mid)
        des[k++] = tower[i++].y;
    while(j <= r)
        des[k++] = tower[j++].y;
    for (i = l; i <= r; i++){
        tower[i].y = des[i];
    }
    num += cnt;
}
void get_num(int l, int r)
{
    if(l >= r - 1){
        if(tower[l].y < tower[r].y){
            num++;
        }
        else{
            int temp = tower[l].y;
            tower[l].y = tower[r].y;
            tower[r].y = temp;
        }
        return;
    }
    int mid = (l + r) >> 1;
    get_num(l, mid);
    get_num(mid + 1, r);
    merge1(l, mid, r);
}

int main()
{
    scanf("%d", &N);
    num = 0;
    for (int i = 0; i < N; i++)
    {
        scanf("%lld %lld", &tower[i].x, &tower[i].y);
    }
    msort(0, N - 1);
    get_num(0, N - 1);
    printf("%lld
", num);
    
   
    return 0;
}
View Code

 

以上是关于灯塔 (数据结构)的主要内容,如果未能解决你的问题,请参考以下文章

四叉树lod结合灯塔AOI

四叉树lod结合灯塔AOI

[入门组模拟赛[难]]灯塔

谷歌页面速度见解。灯塔测量原点

隐身灯塔性能问题

灯塔教育学生账号密码怎么查