P10278 WA 94pts 求调
查看原帖
P10278 WA 94pts 求调
497950
int_4096楼主2024/12/20 17:49

首先,代码非常丑陋。不想看的已经退出去了。
其次,错误大概是端点判错。
求救。

WA 94 pts:

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cassert>
#include <utility>
//#define DEBUG 1
using std::vector;
typedef long long ll;
const int N = 200005;
int q, n;
struct Point {
	int x, y, id;
	void input(const int& _id) {
		scanf("%d%d", &x, &y);
		id = _id;
	}
	void output() {
		fprintf(stderr, "p[%d] = (%d, %d)\n", id, x, y);
	}
};
Point a[N], copy[N], same[N];
int top = 0;
vector<int> G[N];
ll dis(const Point& u, const Point& v) {
	return std::abs(u.x - v.x) + std::abs(u.y - v.y);
}
ll dis_sum[N], ring_dis;
bool cmp_x(const Point& u, const Point& v) {
	return u.x < v.x;
}
bool cmp_y(const Point& u, const Point& v) {
	return u.y < v.y;
}
void add_edge(int u, int v) {
	G[u].push_back(v);
	G[v].push_back(u);
}
void build() { // to build edges;
	for (int i = 1; i <= n; i++)
		copy[i] = a[i];
	std::sort(a + 1, a + 1 + n, cmp_x);
	a[n + 1] = {-1, -1, -1};
	for (int i = 1; i <= n; i++) {
		same[++top] = a[i];
		if (a[i].x != a[i + 1].x) {
			std::sort(same + 1, same + top + 1, cmp_y);
			for (int j = 1; j <= top; j += 2)
				add_edge(same[j].id, same[j + 1].id);
			top = 0;
		}
	} // the same x;
	std::sort(a + 1, a + 1 + n, cmp_y);
	for (int i = 1; i <= n; i++) {
		same[++top] = a[i];
		if (a[i].y != a[i + 1].y) {
			std::sort(same + 1, same + top + 1, cmp_x);
			for (int j = 1; j <= top; j += 2)
				add_edge(same[j].id, same[j + 1].id);
			top = 0;
		}
	} // the same y;
	for (int i = 1; i <= n; i++)
		a[i] = copy[i];
}
Point ring[N];
int rcnt, id[N]; // id 为从编号映射到在环上的位置
bool vis[N];
void dfs(int u) { // to find the circle;
	ring[++rcnt] = a[u];
	vis[u] = 1;
	for (int v : G[u]) {
		if (!vis[v])
			dfs(v);
	}
}
Point dx[N], dy[N];
typedef std::pair<int, int> piir;
const piir BadPos = {-1, -1};
bool check(int num, int l, int r) {
	int pl = std::min(l, r), pr = std::max(l, r);
	return (pl <= num && num <= pr);
}
piir check_x(int x, int y) { // 找(x, y)在垂直于 x 轴的边
	Point idx = {x, y, 0};
	Point* l = std::lower_bound(dx + 1, dx + 1 + n, idx, cmp_x);
	if (l->x != x) return BadPos;
	Point * r = std::upper_bound(dx + 1, dx + 1 + n, idx, cmp_x);
//#ifdef DEBUG
//	fprintf(stderr, "Check_x:: (%d, %d) on  dx- %lld to %lld;\n", x, y, l - dx, r - dx - 1);
//#endif
	int u = std::lower_bound(l, r, idx, cmp_y)->id;
	for (int v : G[u])
		if (a[v].x == a[u].x) {
			piir res = {u, v};
			if (id[u] > id[v]) res = {v, u};
			if (res.first == 1 && res.second == ring[n].id)
				std::swap(res.first, res.second);
			if (!check(y, a[res.first].y, a[res.second].y)) return BadPos;
			return res;
		}
	return BadPos;
}
piir check_y(int x, int y) { // 同上,变为 y 轴
	Point idx = {x, y, 0};
	Point* l = std::lower_bound(dy + 1, dy + 1 + n, idx, cmp_y);
	if (l->y != y) return BadPos;
	Point * r = std::upper_bound(dy + 1, dy + 1 + n, idx, cmp_y);
//#ifdef DEBUG
//	fprintf(stderr, "Check_y:: (%d, %d) on  dx- %lld to %lld;\n", x, y, l - dy, r - dy - 1);
//#endif
	int u = std::lower_bound(l, r, idx, cmp_x)->id;
	for (int v : G[u])
		if (a[v].y == a[u].y) {
			piir res = {u, v};
			if (id[u] > id[v]) res = {v, u};
			if (res.first == 1 && res.second == ring[n].id)
				std::swap(res.first, res.second);
			if (!check(x, a[res.first].x, a[res.second].x)) return BadPos;
			return res;
		}
	return BadPos;
}
piir find(int x, int y) {
	piir r = check_x(x, y), l = check_y(x, y);
#ifdef DEBUG
//	fprintf(stderr, "edge(%d %d) or edge(%d %d)\n", r.first, r.second, l.first, l.second);
#endif
	if (r != BadPos && (l == BadPos || id[l.first] > id[r.first])) return r;
	if (l != BadPos && (r == BadPos || id[r.first] > id[l.first])) return l;
	return r;
}
ll ans[N], rans[N];
void add(int l, int r) {
//	printf("add %d to %d\n", l, r);
	ans[l]++, ans[r + 1]--;
}
void solve() {
	for (int i = 1; i <= n; i++)
		dx[i] = dy[i] = a[i];
	std::sort(dx + 1, dx + 1 + n, cmp_x), dx[n + 1] = {-1, -1, -1};
	for (int i = 1, pre = 1; i <= n; i++)
		if (dx[i].x != dx[i + 1].x)
			std::sort(dx + pre, dx + i + 1, cmp_y), pre = i + 1;
	// 给 x 相同的排序
	std::sort(dy + 1, dy + 1 + n, cmp_y), dy[n + 1] = {-1, -1, -1};
	for (int i = 1, pre = 1; i <= n; i++)
		if (dy[i].y != dy[i + 1].y)
			std::sort(dy + pre, dy + i + 1, cmp_x), pre = i + 1;
	// 同上
	for (int rep = 1, x, y, u, v; rep <= q; rep++) {
		scanf("%d%d%d%d", &x, &y, &u, &v);
		piir f = find(x, y), s = find(u, v);
		if (id[f.first] > id[s.first]) std::swap(f, s), std::swap(x, u), std::swap(y, v);
		piir sx = {x, y}, sy = {u, v};
		if (f.first == s.first && f.second == s.second) {
			int pl = f.first, pr = f.second;
			piir l = {a[pl].x, a[pl].y};
			piir r = {a[pr].x, a[pr].y};
			if (sx == l || sy == l) add(id[pl], id[pl]);
			if (sx == r || sy == r) add(id[pr], id[pr]);
			continue;
		}
		ll dist = dis_sum[id[s.first]] - dis_sum[id[f.second]] + dis({x, y, 0}, a[f.second]) + dis({u, v, 0}, a[s.first]);
		ll rhs = ring_dis - dist;
		if (dist < rhs) {
			add(id[f.second], id[s.first]);
			int pl = f.first;
			piir l = {a[pl].x, a[pl].y};
			if (sx == l || sy == l) add(id[pl], id[pl]);
			int pr = s.second;
			l = {a[pr].x, a[pr].y};
			if (sx == l || sy == l) add(id[pr], id[pr]);
		} else {
			add(1, id[f.first]);
			int pl = f.second;
			piir l = {a[pl].x, a[pl].y};
			if (sx == l || sy == l) add(id[pl], id[pl]);
			if (s.second != 1)
				add(id[s.second], n);
		}
	}
}
int main() {
	//qwq
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
	scanf("%d%d", &q, &n);
	for (int i = 1; i <= n; i++)
		a[i].input(i);
	build();
	dfs(1);
	for (int i = 1; i <= n; i++)
		ring_dis += dis(ring[i], ring[(i == n) ? 1 : i + 1]), id[ring[i].id] = i;
	for (int i = 1; i <= n + 1; i++)
		dis_sum[i] += dis_sum[i - 1] + dis(ring[i], ring[i - 1]);
	solve();
	for (int i = 1; i <= n; i++)
		ans[i] += ans[i - 1];
	for (int i = 1; i <= n; i++)
		rans[ring[i].id] = ans[i];
	for (int i = 1; i <= n; i++)
		printf("%lld\n", rans[i]);
	return 0;
}
2024/12/20 17:49
加载中...