这道题是看04年《线段树的应用》才会的...
各种WA就是因为打错一个字母555555
代码能力有待提升...
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
const int base = 10000;
int N;
struct Point
{
int x, y;
int num;
}v[MAXN], tmp, src[MAXN];
int nextx[MAXN] = {0}, nexty[MAXN] = {0};
int ans = 0;
struct seg
{
int l, r;
int sum;
}tree[base<<3] = {0};
bool cmpx(const Point &A, const Point &B)
{
if(A.x != B.x) return A.x < B.x;
else return A.y < B.y;
}
bool cmpy(const Point &A, const Point &B)
{
if(A.y != B.y) return A.y < B.y;
else return A.x < B.x;
}
bool check()
{
bool used[MAXN] = {false};
for(int i = 1, pd = 1; !used[i];)
{
used[i] = true;
if(pd) i = nextx[i];
else i = nexty[i];
pd ^= 1;
}
for(int i = 1; i <= N; ++i)
if(!used[i]) return false;
return true;
}
void insert(int x, int num)
{
int mid = (tree[num].l+tree[num].r)>>1;
tree[num].sum++;
if(tree[num].l == tree[num].r) return;
if(x <= mid) insert(x, num<<1);
else insert(x, (num<<1)+1);
}
void cancel(int x, int num)
{
int mid = (tree[num].l+tree[num].r)>>1;
tree[num].sum--;
if(tree[num].l == tree[num].r) return;
if(x <= mid) cancel(x, num<<1);
else cancel(x, (num<<1)+1);
}
int search(int d, int u, int num)
{
int l = tree[num].l, r = tree[num].r;
int mid = (l+r)>>1;
if(l == d && r == u) return tree[num].sum;
if(u <= mid) return search(d, u, num<<1);
else if(d > mid) return search(d, u, (num<<1)+1);
else return search(d, mid, num<<1)+search(mid+1, u, (num<<1)+1);
}
void work()
{
<pre name="code" class="cpp"> bool hash[MAXN] = {0};
for(int i = 1; i <= N; ++i)
{
hash[v[i].num] = true;
if(!hash[nextx[v[i].num]]) insert(v[i].y, 1);
else cancel(v[i].y, 1);
if(!hash[nexty[v[i].num]] && src[v[i].num].y <= src[nexty[v[i].num]].y-2 && search(src[v[i].num].y+1, src[nexty[v[i].num]].y-1, 1) > 0)
{
printf("0");
return;
}
}
printf("%d", ans);
}
void make(int l, int r, int num)
{
int mid = (l+r)>>1;
tree[num].l = l, tree[num].r = r;
if(l == r) return;
make(l, mid, num<<1);
make(mid+1, r, (num<<1)+1);
}
int main()
{
make(0, base<<1, 1);
scanf("%d", &N);
for(int i = 1; i <= N; ++i)
{
scanf("%d%d", &v[i].x, &v[i].y);
v[i].x += base, v[i].y += base;
v[i].num = i;
src[i] = v[i];
}
sort(v+1, v+N+1, cmpy);
for(int i = 1; i < N;)
if(v[i].y == v[i+1].y)
{
nextx[v[i].num] = v[i+1].num;
nextx[v[i+1].num] = v[i].num;
ans += v[i+1].x-v[i].x;
i += 2;
}
else
{
printf("0");
return 0;
}
sort(v+1, v+N+1, cmpx);
for(int i = 1; i < N;)
if(v[i].x == v[i+1].x)
{
nexty[v[i].num] = v[i+1].num;
nexty[v[i+1].num] = v[i].num;
ans += v[i+1].y-v[i].y;
i += 2;
}
else
{
printf("0");
return 0;
}
if(!check())
{
printf("0");
return 0;
}
work();
return 0;
}