POJ3109-Inner Vertices

来源:互联网 发布:mac expect ssh 编辑:程序博客网 时间:2024/06/06 01:30

Inner Vertices
Time Limit: 5000MS Memory Limit: 65536KTotal Submissions: 2583 Accepted: 739Case Time Limit: 2000MS

Description

There is an infinite square grid. Some vertices of the grid are black and other vertices are white.

A vertex V is called inner if it is both vertical-inner and horizontal-inner. A vertex V is called horizontal-inner if there are two such black vertices in the same row that V is located between them. A vertex V is called vertical-inner if there are two such black vertices in the same column that V is located between them.

On each step all white inner vertices became black while the other vertices preserve their colors. The process stops when all the inner vertices are black.

Write a program that calculates a number of black vertices after the process stops.

Input

The first line of the input file contains one integer number n (0 ≤ n ≤ 100 000) — number of black vertices at the beginning.

The following n lines contain two integer numbers each — the coordinates of different black vertices. The coordinates do not exceed 109 by their absolute values.

Output

Output the number of black vertices when the process stops. If the process does not stop, output -1.

Sample Input

40 22 0-2 00 -2

Sample Output

5

Hint

Source

Northeastern Europe 2005, Northern Subregion


题意:一个无限大的棋盘上有无数个点,这些点有黑有白,如果有一个点,上下左右各有点,则将这个点涂成黑色。最后计算这个棋盘上黑点的数量

解题思路:先将坐标离散化,然后判断出对于每个x轴的最高的y。对所有点可以按y轴从小到大进行排序,y轴相同的按x轴从小到大进行排序。每扫到一个点,若这个点不是这个x轴的最高的y,则在线段树上将这个位置置为一,否则的话置为0。扫的时候若前后两个点的y坐标一样,则查询一下在这两个x轴之间区间值为多少,则答案就加多少


#include <iostream>    #include <cstdio>    #include <string>    #include <cstring>    #include <algorithm>    #include <cmath>    #include <vector>    #include <map>    #include <set>    #include <queue>    #include <stack>    #include <functional>    #include <climits>    using namespace std;#define LL long long    const int INF = 0x3f3f3f3f;int n, x[100009], y[100009], sum[100009 << 2], f[100009];struct point{int x, y;bool operator<(const point &b)const{if (y != b.y) return y < b.y;else return x < b.x;}}p[100009];void update(int k, int l, int r, int p, int val){if (l == r) { sum[k] = val; return; }int mid = (l + r) >> 1;if (mid >= p) update(k << 1, l, mid, p, val);else update(k << 1 | 1, mid + 1, r, p, val);sum[k] = sum[k << 1] + sum[k << 1 | 1];}int query(int k, int l, int r, int ll, int rr){if (l >= ll&&r <= rr) return sum[k];int mid = (l + r) >> 1, ans = 0;if (ll <= mid) ans += query(k << 1, l, mid, ll, rr);if (rr > mid) ans += query(k << 1 | 1, mid + 1, r, ll, rr);return ans;}int main(){while (~scanf("%d", &n)){memset(f, 0, sizeof f);int cnt1 = 1, cnt2 = 1;for (int i = 1; i <= n; i++){scanf("%d%d", &p[i].x, &p[i].y);x[cnt1++] = p[i].x, y[cnt2++] = p[i].y;}sort(p + 1, p + 1 + n);sort(x + 1, x + cnt1);sort(y + 1, y + cnt2);cnt1 = unique(x + 1, x + cnt1) - x;cnt2 = unique(y + 1, y + cnt2) - y;memset(sum, 0, sizeof sum);for (int i = n; i >= 1; i--){int xx = lower_bound(x + 1, x + cnt1, p[i].x) - x;int yy = lower_bound(y + 1, y + cnt2, p[i].y) - y;if (f[xx]) continue;f[xx] = yy;}int ans = 0;for (int i = 1; i <= n; i++){int xx = lower_bound(x + 1, x + cnt1, p[i].x) - x;int yy = lower_bound(y + 1, y + cnt2, p[i].y) - y;if (f[xx] > yy) update(1, 1, cnt1, xx, 1);else update(1, 1, cnt1, xx, 0);if (i == 1 || p[i].y != p[i - 1].y) continue;int l = lower_bound(x + 1, x + cnt1, p[i - 1].x) - x + 1;int r = xx - 1;if (l > r) continue;ans += query(1, 1, cnt1, l, r);}printf("%d\n", ans + n);}return 0;}