RT,不知道哪里寄了。
#include <bits/stdc++.h>
#define rint register int
#define int long long
#define endl '\n'
#define mp make_pair
using namespace std;
const int N = 4e5 + 5;
const int Z = 4e6 + 5;
const int M = 1e3 + 5;
int c, n, m, q;
int tot1, tot2, tot3;
int cnt;
int a[N << 1], ans;
vector<int> v[N];
map<pair<int, int>, int> p;
struct ScanLine
{
int l, r, h;
int mark;
friend bool operator < (ScanLine a, ScanLine b)
{
return a.h < b.h;
}
} b[N << 1], line[M];
struct Node
{
int l, r;
int sum;
int len;
} t[Z];
#define ls p << 1
#define rs p << 1 | 1
void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
t[p].len = t[p].sum = 0;
if (l == r) return;
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
}
int find(int t)
{
int l = 1, r = tot2;
while (l < r)
{
int mid = (l + r) >> 1;
if (a[mid] >= t) r = mid;
else l = mid + 1;
}
return l;
}
void push_up(int p)
{
if (t[p].sum) t[p].len = a[t[p].r + 1] - a[t[p].l];
else t[p].len = t[ls].len + t[rs].len;
}
void change(int p, int l, int r, int c)
{
if (t[p].l == l && t[p].r == r)
{
t[p].sum += c;
push_up(p);
return ;
}
int mid = (t[p].l + t[p].r) >> 1;
if (r <= mid) change(ls, l, r, c);
else if (l > mid) change(rs, l, r, c);
else change(ls, l, mid, c), change(rs, mid + 1, r, c);
push_up(p);
}
signed main()
{
cin >> c >> n >> m >> q;
while (q--)
{
int t;
cin >> t;
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
if (x1 != x2 && y1 != y2)
{
line[++cnt].l = x1;
line[cnt].r = x2;
line[cnt].h = y1;
continue;
}
tot1++;
b[tot1 * 2 - 1] = {x1, x2, y1, 1};
b[tot1 * 2] = {x1, x2, y2, -1};
a[tot1 * 2 - 1] = x1;
a[tot1 * 2] = x2;
}
while (1)
{
int cnt = 0;
for (rint i = 1; i <= cnt; i++)
{
for (rint j = 1; j <= cnt; j++)
{
if (j != i && line[i].h && line[j].h && line[i].h - line[i].l == line[j].h - line[j].l)
{
if (line[j].l >= line[i].l && line[j].r <= line[i].r || line[i].l <= line[j].l && line[j].l <= line[i].r && line[i].r <= line[j].r)
{
cnt++;
line[i].l = min(line[i].l, line[j].l);
line[i].r = max(line[i].r, line[j].r);
line[i].h = min(line[i].h, line[j].h);
line[j].h = 0;
}
}
}
}
if (!cnt) break;
}
for (rint i = 1; i <= cnt; i++)
{
if (line[i].h)
{
ans += line[i].r - line[i].l + 1;
}
}
for (rint i = 1; i <= 2 * tot1; i += 2)
{
if (b[i].h == b[i + 1].h)
{
if (!p[mp(b[i].h, 0)])
{
p[mp(b[i].h, 0)] = ++tot3;
}
v[p[mp(b[i].h, 0)]].push_back(i);
}
else if (b[i].l == b[i].r)
{
if (!p[mp(0, b[i].l)])
{
p[mp(0, b[i].l)] = ++tot3;
}
v[p[mp(0, b[i].l)]].push_back(i);
}
}
for (rint i = 1; i <= cnt; i++)
{
if (!line[i].h) continue;
for (rint j = 1; j <= 2 * tot1; j += 2)
{
int x = b[j].h - line[i].h + line[i].l;
int y = b[j].l + line[i].h - line[i].l;
if (b[j].l == b[j].r && b[j].l >= line[i].l && b[j].l <= line[i].r && y >= b[j].h && y <= b[j + 1].h)
{
if (!p[mp(b[j].l, y)])
{
p[mp(b[j].l, y)] = 1;
ans--;
}
}
else if (b[j].h == b[j + 1].h && b[j].h >= line[i].h && b[j].h <= line[i].h + line[i].r - line[i].l && x >= b[j].l && x <= b[j].r)
{
if (!p[mp(x, b[j].h)])
{
p[mp(x, b[j].h)] = 1;
ans--;
}
}
}
}
for (rint i = 1; i <= 2 * tot1; i++)
{
b[i].l--;
if (i & 1)
{
b[i].h--;
a[i]--;
}
}
sort(a + 1, a + 1 + 2 * tot1);
sort(b + 1, b + 1 + 2 * tot1);
tot2 = unique(a + 1, a + 1 + 2 * tot1) - a - 1;
build(1, 1, tot2);
for (rint i = 1; i < 2 * tot1; i++)
{
int l = find(b[i].l);
int r = find(b[i].r) - 1;
change(1, l, r, b[i].mark);
ans += t[1].len * (b[i + 1].h - b[i].h);
}
cout << ans << endl;
return 0;
}