代码:
//扫描线经典题目
//洛谷 P5490 【模板】扫描线 HDU 1542 Mars Map
//https://www.luogu.com.cn/problem/P5490
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=105;
struct edge{
int l, r, h;
int f; //1为下边界,-1为上边界
}ss[maxn*2];
bool cmp(edge x, edge y){
return x.h < y.h;
}
int n, m;
int pos[maxn*2];
struct tree{
int l, r, cnt; //cnt:覆盖了多少次
int len; //被覆盖了多长
}t[maxn*4];
void build(int p, int l, int r){
t[p].l = l;
t[p].r = r;
t[p].cnt = 0;
t[p].len = 0;
if (l == r)
return;
int mid=(l+r)/2;
build(p*2, l, mid);
build(p*2+1, mid+1, r);
}
void pushup(int p){
if (t[p].cnt)
t[p].len = pos[t[p].r+1] - pos[t[p].l];
else if (t[p].l == t[p].r)
t[p].len = 0;
else
t[p].len = t[p*2].len + t[p*2+1].len;
}
void update(int p, int l, int r, int val){
if (l <= t[p].l && r >= t[p].r){
t[p].cnt += val;
pushup(p);
return;
}
int mid=(t[p].l+t[p].r)/2;
if (l <= mid)
update(p*2, l, r, val);
if (r > mid)
update(p*2+1, l, r, val);
pushup(p);
}
int binary(int k){
int l=1, r=m;
while (l < r){
int mid=(l+r)/2;
if (pos[mid] >= k)
r = mid;
else
l = mid + 1;
}
return l;
}
signed main(){
cin >> n;
int num=1;
for (int i=1; i<=n; i++){
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
ss[num].l = x1;
ss[num].r = x2;
ss[num].h = y1;
ss[num].f = 1;
ss[num+1].l = x1;
ss[num+1].r = x2;
ss[num+1].h = y2;
ss[num+1].f = -1;
pos[num] = x1;
pos[num+1] = x2;
num += 2;
}
num--;
sort(ss+1, ss+num+1, cmp);
sort(pos+1, pos+num+1);
m = 0;
pos[0] = -1;
for (int i=1; i<=num; i++)
if (pos[i] != pos[i-1])
pos[++m] = pos[i]; //去重
build(1, 1, m);
int ans=0;
for (int i=1; i<num; i++){
int l=binary(ss[i].l);
int r=binary(ss[i].r)-1; //离散化
update(1, l, r, ss[i].f);
ans += (ss[i+1].h - ss[i].h) * t[1].len;
}
cout << ans << '\n';
return 0;
}