本题就是一个扫描线的模板题,但是需要改一下线段树的中存储的信息,每个结点需要存储一下当前结点下多少长度是被奇(或偶数)个矩形覆盖的即可。
并且本题的坐标范围很大,但是个数很少,所以可以离散化一下再做。
本代码应该无任何问题了,如果有佬发现有问题请及时私聊我更改哦~
#include
#define IO (ios::sync_with_stdio(false), cin.tie(0), cout.tie(0))
#define INF 0x3f3f3f3f
#define ll long long
#define pii pair
#define pll pair
#define vs vector
#define pk push_back
#define vss vector >
#define sz(x) (int)(x).size()
#define mk(a, b) make_pair(a, b)
#define Max(a, b) (a > b ? a : b)
#define Min(a, b) (a < b ? a : b)
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define rep(a, b, c) for(register int a = b; a <= c; ++ a)
#define per(a, b, c) for(register int a = b; a >= c; -- a)
using namespace std;
const int N = 1e5 + 5;
int n, m, T;
int alls[N << 2];
struct Segment
{
int x, y1, y2;
int k;
bool operator< (const Segment &q) const {
return x < q.x;
}
} seg[N << 2];
struct Node
{
int l, r;
int cnt;
int len1, len2;
}tr[N << 4];
template<class T>
inline void read(T &x)
{
x = 0; T f = 1; char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x *= f;
}
template<class T>
inline void write(T x)
{
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int get(double x)
{
return lower_bound(alls, alls + m, x) - alls;
}
void build(int u, int l, int r)
{
tr[u] = {
l, r};
if(l >= r) return;
int mid = l + r >> 1;
build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r);
}
void pushup(int u)
{
if(tr[u].cnt)
{
if(tr[u].cnt & 1)
{
tr[u].len1 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
tr[u].len2 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
tr[u].len1 += alls[tr[u].r + 1] - alls[tr[u].l] - tr[u].len1 - tr[u].len2;
}
else
{
tr[u].len2 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
tr[u].len1 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
tr[u].len2 += alls[tr[u].r + 1] - alls[tr[u].l] - tr[u].len1 - tr[u].len2;
}
}
else if(tr[u].l != tr[u].r)
{
tr[u].len1 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
tr[u].len2 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
}
else tr[u].len1 = tr[u].len2 = 0;
}
void modify(int u, int l, int r, int k)
{
if(tr[u].l >= l && tr[u].r <= r)
{
tr[u].cnt += k;
pushup(u);
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(u << 1, l, r, k);
if(r > mid) modify(u << 1 | 1, l, r, k);
pushup(u);
}
int main()
{
scanf("%d", &n);
m = 0;
for(int i = 0; i < n; i ++ )
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
alls[m] = y1; seg[m ++ ] = {
x1, y1, y2, 1};
alls[m] = y2; seg[m ++ ] = {
x2, y1, y2, -1};
}
sort(seg, seg + m);
sort(alls, alls + m);
m = unique(alls, alls + m) - alls;
build(1, 0, m - 2);
ll res1 = 0, res2 = 0;
for(int i = 0; i < n << 1; i ++ )
{
if(i)
{
res1 += tr[1].len1 * 1ll * (seg[i].x - seg[i - 1].x);
res2 += tr[1].len2 * 1ll * (seg[i].x - seg[i - 1].x);
}
modify(1, get(seg[i].y1), get(seg[i].y2) - 1, seg[i].k);
}
printf("%lld\n%lld\n", res1, res2);
return 0;
}