扫描线求调
查看原帖
扫描线求调
524911
PassName楼主2024/4/27 14:14

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;
}
2024/4/27 14:14
加载中...