On this page
article
Area da Uniao de Retangulos
Sobre
O(n log(n))
5d8d2f
Link original: areaUniaoRetangulo.cpp
Código
namespace seg {
pair<int, ll> seg[4*MAX];
ll lazy[4*MAX], *v;
int n;
pair<int, ll> merge(pair<int, ll> l, pair<int, ll> r){
if (l.second == r.second) return {l.first+r.first, l.second};
else if (l.second < r.second) return l;
else return r;
}
pair<int, ll> build(int p=1, int l=0, int r=n-1) {
lazy[p] = 0;
if (l == r) return seg[p] = {1, v[l]};
int m = (l+r)/2;
return seg[p] = merge(build(2*p, l, m), build(2*p+1, m+1, r));
}
void build(int n2, ll* v2) {
n = n2, v = v2;
build();
}
void prop(int p, int l, int r) {
seg[p].second += lazy[p];
if (l != r) lazy[2*p] += lazy[p], lazy[2*p+1] += lazy[p];
lazy[p] = 0;
}
pair<int, ll> query(int a, int b, int p=1, int l=0, int r=n-1) {
prop(p, l, r);
if (a <= l and r <= b) return seg[p];
if (b < l or r < a) return {0, LINF};
int m = (l+r)/2;
return merge(query(a, b, 2*p, l, m), query(a, b, 2*p+1, m+1, r));
}
pair<int, ll> update(int a, int b, int x, int p=1, int l=0, int r=n-1) {
prop(p, l, r);
if (a <= l and r <= b) {
lazy[p] += x;
prop(p, l, r);
return seg[p];
}
if (b < l or r < a) return seg[p];
int m = (l+r)/2;
return seg[p] = merge(update(a, b, x, 2*p, l, m),
update(a, b, x, 2*p+1, m+1, r));
}
};
ll seg_vec[MAX];
ll area_sq(vector<pair<pair<int, int>, pair<int, int>>> &sq){
vector<pair<pair<int, int>, pair<int, int>>> up;
for (auto it : sq){
int x1, y1, x2, y2;
tie(x1, y1) = it.first;
tie(x2, y2) = it.second;
up.push_back({{x1+1, 1}, {y1, y2}});
up.push_back({{x2+1, -1}, {y1, y2}});
}
sort(up.begin(), up.end());
memset(seg_vec, 0, sizeof seg_vec);
ll H_MAX = MAX;
seg::build(H_MAX-1, seg_vec);
auto it = up.begin();
ll ans = 0;
while (it != up.end()){
ll L = (*it).first.first;
while (it != up.end() && (*it).first.first == L){
int x, inc, y1, y2;
tie(x, inc) = it->first;
tie(y1, y2) = it->second;
seg::update(y1+1, y2, inc);
it++;
}
if (it == up.end()) break;
ll R = (*it).first.first;
ll W = R-L;
auto jt = seg::query(0, H_MAX-1);
ll H = H_MAX - 1;
if (jt.second == 0) H -= jt.first;
ans += W*H;
}
return ans;
}