View Code
#include<bits/stdc++.h>
using namespace std;
using lf = double;
using ll = long long;
using ull = unsigned long long;
const int maxn = 2e5 + 5; // two scan lines
struct scanline{
lf y;
lf left_x, right_x;
int inout;
scanline(){}
scanline(lf y_, lf l, lf r, int io) : y(y_), left_x(l), right_x(r), inout(io) {}
} tree[maxn << 2];
int lazy_tag[maxn << 2];
lf length[maxn << 2], x[maxn];
int num, n, cnt, t = 0;
bool cmp(const scanline &a, const scanline &b) {return a.y < b.y;} // sort by y
ll ls(ll id) {return id << 1;}
ll rs(ll id) {return id << 1 | 1;}
void maintain(ll id, ll left, ll right) {
if (lazy_tag[id]) length[id] = x[right] - x[left];
else if (left + 1 == right) length[id] = 0; // leaf node
else length[id] = length[ls(id)] + length[rs(id)];
}
void update(ll L, ll R, ll io, ll id = 1, ll left = 1, ll right = num) {
if (L <= left and right <= R){
lazy_tag[id] += io;
maintain(id, left, right);
return ;
}
if (left == right) return ;
ll mid = (left + right) >> 1;
if (L < mid) update(L, R, io, ls(id), left, mid);
if (R > mid) update(L, R, io, rs(id), mid, right);
maintain(id, left, right);
}
void solve() {
cin >> n;
if (!n) exit(0);
cnt = 0;
while (n--) {
lf x1, x2, y_1, y_2;
cin >> x1 >> y_1 >> x2 >> y_2;
tree[++cnt] = {y_1, x1, x2, 1};
x[cnt] = x1;
tree[++cnt] = {y_2, x1, x2, -1};
x[cnt] = x2;
}
sort(x + 1, x + cnt + 1);
sort(tree + 1, tree + cnt + 1, cmp);
num = unique(x + 1, x + cnt + 1) - (x + 1);
memset(lazy_tag, 0, sizeof lazy_tag);
memset(length, 0, sizeof length);
lf ans = 0;
for (int i = 1; i <= cnt; i++) {
ans += length[1] * (tree[i].y - tree[i - 1].y);
ll L = lower_bound(x + 1, x + num + 1, tree[i].left_x) - x;
ll R = lower_bound(x + 1, x + num + 1, tree[i].right_x) - x;
update(L, R, tree[i].inout);
}
//Test case #1
//Total explored area: 180.00
cout << "Test case #" << ++t << "\n";
cout << "Total explored area: " << fixed << setprecision(2) << ans << "\n\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// freopen("T1.in", "r", stdin);
// freopen("T1.out", "w", stdout);
int T = 1;
// cin >> T;
while (T) solve();
return 0;
}
矩形周长并
View Code
#include <bits/stdc++.h>
using namespace std;
using lf = double;
using ll = long long;
using ull = unsigned long long;
const int maxn = 2e5 + 5;
struct scanline {
int y;
ll left_x, right_x;
int inout;
scanline() {}
scanline(int y_, ll l, ll r, int io) : y(y_), left_x(l), right_x(r), inout(io) {}
} tree[maxn << 2];
int lazy_tag[maxn << 2];
ll length[maxn << 2];
ll cover_num[maxn << 2];
ll lcover[maxn << 2];
ll rcover[maxn << 2];
ll x[maxn];
int num, n, cnt;
bool cmp(const scanline &a, const scanline &b) {
if (a.y != b.y) return a.y < b.y;
return a.inout > b.inout;
}
ll ls(ll id) { return id << 1; }
ll rs(ll id) { return id << 1 | 1; }
void maintain(ll id, ll left, ll right) {
if (lazy_tag[id]) {
length[id] = x[right] - x[left];
cover_num[id] = 1;
lcover[id] = rcover[id] = 1;
} else if (left + 1 == right) {
length[id] = 0;
cover_num[id] = 0;
lcover[id] = rcover[id] = 0;
} else {
length[id] = length[ls(id)] + length[rs(id)];
cover_num[id] = cover_num[ls(id)] + cover_num[rs(id)];
if (rcover[ls(id)] and lcover[rs(id)])
cover_num[id]--;
lcover[id] = lcover[ls(id)];
rcover[id] = rcover[rs(id)];
}
}
void update(ll L, ll R, ll io, ll id = 1, ll left = 1, ll right = num) {
if (L <= left and right <= R) {
lazy_tag[id] += io;
maintain(id, left, right);
return;
}
if (left + 1 == right) return;
ll mid = (left + right) >> 1;
if (L < mid) update(L, R, io, ls(id), left, mid);
if (R > mid) update(L, R, io, rs(id), mid, right);
maintain(id, left, right);
}
void solve() {
cin >> n;
cnt = 0;
for (int i = 0; i < n; i++) {
int x1, x2, y_1, y_2;
cin >> x1 >> y_1 >> x2 >> y_2;
tree[++cnt] = {y_1, x1, x2, 1};
x[cnt] = x1;
tree[++cnt] = {y_2, x1, x2, -1};
x[cnt] = x2;
}
sort(x + 1, x + cnt + 1);
num = unique(x + 1, x + cnt + 1) - (x + 1);
sort(tree + 1, tree + cnt + 1, cmp);
memset(lazy_tag, 0, sizeof(lazy_tag));
memset(length, 0, sizeof(length));
memset(cover_num, 0, sizeof(cover_num));
memset(lcover, 0, sizeof(lcover));
memset(rcover, 0, sizeof(rcover));
ll ans = 0;
ll last_length = 0;
for (int i = 1; i <= cnt; i++) {
ll L = lower_bound(x + 1, x + num + 1, tree[i].left_x) - x;
ll R = lower_bound(x + 1, x + num + 1, tree[i].right_x) - x;
update(L, R, tree[i].inout);
ans += cover_num[1] * 2 * (tree[i + 1].y - tree[i].y);
ans += abs(length[1] - last_length);
last_length = length[1];
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
// freopen("T1.in", "r", stdin);
// freopen("T1.out", "w", stdout);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}