Tsinghua OJ ~ 数据结构 MOOC ~ PA1 ~ 灯塔(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.

Solution

#include <cstdio>

const int SZ = 1 << 20; //快速io
struct fastio
{
    char inbuf[SZ];
    char outbuf[SZ];
    fastio()
    {
        setvbuf(stdin, inbuf, _IOFBF, SZ);
        setvbuf(stdout, outbuf, _IOFBF, SZ);
    }
} io;

const int maxn = 4e6 + 1;
using ll = long long;
struct node
{
    int x, y;
} a[maxn], b[maxn];
ll count = 0;

// 按照 x 升序排列
void mergeX(int lo, int mi, int hi)
{
    int i = lo, j = mi;
    for (int k = lo; k != hi; ++k)
    {
        // 这里用了两个 node 来操作,所以不用复制子序列出来
        if (hi <= j || (i < mi && (a[i].x < a[j].x || (a[i].x == a[j].x && a[i].y < a[j].y))))
            b[k] = a[i++];
        else
            b[k] = a[j++];
    }
    for (int k = lo; k != hi; ++k)
        a[k] = b[k];
}

void mergeSortX(int lo, int hi)
{
    if (hi - lo < 2)
        return;
    int mi = (hi + lo) >> 1;
    mergeSortX(lo, mi);
    mergeSortX(mi, hi);
    mergeX(lo, mi, hi);
}

void mergeY(int lo, int mi, int hi)
{
    int i = lo, j = mi;
    for (int k = lo; k != hi; ++k)
    {
        // i <  j 则 j 的右侧都更大,个数为 (hi - 1) - (j - 1)
        if (hi <= j || (i < mi && a[i].y < a[j].y))
            b[k] = a[i++], count += hi - j;
        else
            b[k] = a[j++];
    }
    for (int k = lo; k != hi; ++k)
        a[k] = b[k];
}

void mergeSortY(int lo, int hi)
{
    if (hi - lo < 2)
        return;
    int mi = (hi + lo) >> 1;
    mergeSortY(lo, mi);
    mergeSortY(mi, hi);
    mergeY(lo, mi, hi);
}

int main()
{
    ll n;
    scanf("%lld", &n);
    for (int i = 0; i != n; ++i)
    {
        scanf("%d %d", &a[i].x, &a[i].y);
    }
    mergeSortX(0, n);
    mergeSortY(0, n);
    printf("%lld\n", count);
    return 0;
}

https://dsa.cs.tsinghua.edu.cn/oj/result/3088fde1b47648d0831755be30e37a6eea4659f2.html

上一篇:宏LONG_MAX和LLONG_MAX


下一篇:java模仿网络爬虫简单案例