Description
给出n个矩形,若某条边的一段被某个矩形覆盖,则这一段就会消失,求剩下的边的总长度。
Solution
那一天wjp终于想起了usaco帐号
咳咳,扫描线+离散+线段树,把一个矩形拆成四条线段做就行了
这里n有5000,线段树一艹到底显然是不行的。那么我们用 Ci 表示i节点被覆盖了多少次, Vi 表示i节点的覆盖状态,0、1、2分别表示完全没覆盖、部分覆盖、全覆盖,然后就a了
实测poj1777不能过,大概是vector的锅
据说暴力扫描是可以的
Code
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define fill(x, t) memset(x, t, sizeof(x))
#define pb push_back
#define N 10001
using namespace std;
struct treeNode{int l, r, c, v;}t[N * 5 + 1];
struct data{int x, ind;};
struct seg{int x, l, r, v;};
int hy[N], lx[N], len;
inline void modify(int now, int l, int r, int v){
int mid = (t[now].l + t[now].r) >> 1;
if (t[now].l == l && t[now].r == r){
if (t[now].v == 0){
t[now].v = 2;
t[now].c += v;
if (!t[now].c || t[now].c == v){
len += lx[t[now].r] - lx[t[now].l];
}
}else if (t[now].v == 1){
modify(now * 2, l, mid, v);
modify(now * 2 + 1, mid, r, v);
}else if (t[now].v == 2){
t[now].c += v;
if (!t[now].c || t[now].c == v){
len += lx[t[now].r] - lx[t[now].l];
}
}
return;
}
if (t[now].v == 2){
t[now * 2].v = t[now * 2 + 1].v = 2;
t[now * 2].c += t[now].c;
t[now * 2 + 1].c += t[now].c;
}
t[now].v = 1;
if (r <= mid){
modify(now * 2, l, r, v);
}else if (l >= mid){
modify(now * 2 + 1, l, r, v);
}else{
modify(now * 2, l, mid, v);
modify(now * 2 + 1, mid, r, v);
}
}
inline void build(int now, int l, int r){
t[now] = (treeNode){l, r, 0, 0};
if (l + 1 == r){
return;
}
int mid = (t[now].l + t[now].r) >> 1;
build(now * 2, l, mid);
build(now * 2 + 1, mid, r);
}
inline int cmp1(data a, data b){
return a.x < b.x;
}
inline int cmp2(seg a, seg b){
return a.x < b.x || a.x == b.x && a.v > b.v;
}
inline void solve(vector<int> u, vector<int> d, vector<int> l, vector<int> r){
vector<data> p;
vector<seg> s;
rep(i, 1, u.size()){
p.pb((data){l[i - 1], i * 2 - 1});
p.pb((data){r[i - 1], i * 2});
s.pb((seg){d[i - 1], i * 2 - 1, i * 2, 1});
s.pb((seg){u[i - 1], i * 2 - 1, i * 2, -1});
}
sort(p.begin(), p.end(), cmp1);
sort(s.begin(), s.end(), cmp2);
fill(hy, 0);
fill(lx, 0);
fill(t, 0);
int cnt = 1;
hy[p[0].ind] = cnt;
lx[cnt] = p[0].x;
rep(i, 1, p.size() - 1){
if (p[i].x != p[i - 1].x){
cnt += 1;
}
hy[p[i].ind] = cnt;
lx[cnt] = p[i].x;
}
rep(i, 0, s.size() - 1){
s[i].l = hy[s[i].l];
s[i].r = hy[s[i].r];
}
build(1, 1, cnt);
rep(i, 0, s.size() - 1){
modify(1, s[i].l, s[i].r, s[i].v);
}
// printf("%d\n", len);
}
int main(void){
int n;
scanf("%d", &n);
vector<int> u, d, l, r;
rep(i, 1, n){
int tu, td, tl, tr;
scanf("%d%d%d%d", &tl, &td, &tr, &tu);
l.pb(tl);
d.pb(td);
r.pb(tr);
u.pb(tu);
}
solve(u, d, l, r);
solve(r, l, d, u);
printf("%d\n", len);
return 0;
}