求助
查看原帖
求助
554746
yiming564楼主2023/12/27 23:02
#include <bits/stdc++.h>

int64_t n, m, k;

struct point_t
{
	int64_t x;
	int64_t y;
};

struct line_t
{
	int64_t bound;
	int64_t k;
	int64_t b;
};

std::vector<point_t> point;
std::vector<int64_t> point_x, point_y;
std::vector<line_t> line_x, line_y;

auto cmp = [](point_t a, point_t b)
{
	if (a.x < b.x)
		return true;
	else if (a.x > b.x)
		return false;
	return a.y < b.y;
};

auto cmp_line = [](line_t a, line_t b)
{
	return a.bound < b.bound;
};

inline int64_t calculate(int64_t px, int64_t py)
{
	int64_t ans = 0;
	for (int i = 0; i < k; i++)
		ans += abs(point[i].x - px) + abs(point[i].y - py);
	return ans;
}

inline int64_t calculate_x(int64_t px)
{
	int64_t ans = 0;
	for (int i = 0; i < k; i++)
		ans += abs(point[i].x - px);
	return ans;
}

inline int64_t calculate_y(int64_t py)
{
	int64_t ans = 0;
	for (int i = 0; i < k; i++)
		ans += abs(point[i].y - py);
	return ans;
}

inline line_t get_line(point_t a, point_t b)
{
	return (line_t){b.x, (a.y - b.y) / (a.x - b.x), (b.y * a.x - a.y * b.x) / (a.x - b.x)};
}

void init()
{
	for (auto &&i : point)
	{
		point_x.push_back(i.x);
		point_y.push_back(i.y);
	}
	
	auto it = point_x.begin();
	auto prev_it = it;
	int64_t prev = calculate_x(*it);
	line_x.push_back((line_t){*it, -k, prev + k * *it});
	int64_t next = prev, point_sum = 0;
	while ((it = std::upper_bound(point_x.begin(), point_x.end(), *it)) != point_x.end())
	{
		point_sum = std::distance(point_x.begin(), it);
		next += point_sum * (*it - *prev_it);
		next -= (k - point_sum) * (*it - *prev_it);
		line_x.push_back(get_line((point_t){*prev_it, prev}, (point_t){*it, next}));
		prev = next;
		prev_it = it;
	}
	line_x.push_back((line_t){n, k, prev - k* *prev_it});
	
	std::sort(point_y.begin(), point_y.end());
	it = point_y.begin();
	prev_it = it;
	prev = calculate_y(*it);
	line_y.push_back((line_t){*it, -k, prev + k * *it});
	next = prev, point_sum = 0;
	while ((it = std::upper_bound(point_y.begin(), point_y.end(), *it)) != point_y.end())
	{
		point_sum = std::distance(point_y.begin(), it);
		next += point_sum * (*it - *prev_it);
		next -= (k - point_sum) * (*it - *prev_it);
		line_y.push_back(get_line((point_t){*prev_it, prev}, (point_t){*it, next}));
		prev = next;
		prev_it = it;
	}
	line_y.push_back((line_t){m, k, prev - k* *prev_it});
}

inline int64_t x_sum(int64_t x)
{
	auto it = std::lower_bound(line_x.begin(), line_x.end(), (line_t){x, 0, 0}, cmp_line);
	return it->k * x + it->b;
}

inline int64_t y_sum(int64_t y)
{
	auto it = std::lower_bound(line_y.begin(), line_y.end(), (line_t){y, 0, 0}, cmp_line);
	return it->k * y + it->b;
}

inline int64_t sum(int64_t x, int64_t y)
{
	return x_sum(x) + y_sum(y);
}

inline bool valid(int64_t x, int64_t y)
{
	return 1 <= x && x <= n && 1 <= y && y <= m;
}

inline bool exist(int64_t x, int64_t y)
{
	auto it = std::lower_bound(point.begin(), point.end(), (point_t){x, y}, cmp);
	return it != point.end() && it->x == x && it->y == y;
}

int64_t ans = 0;
inline void push_vertex(int64_t x, int64_t y)
{
	if (!exist(x + 1, y) && valid(x + 1, y))
	{
		int64_t result = sum(x + 1, y);
		// assert(result == calculate(x + 1, y));
		if (ans < result)
			ans = result;
	}
	if (!exist(x - 1, y) && valid(x - 1, y))
	{
		int64_t result = sum(x - 1, y);
		// assert(result == calculate(x - 1, y));
		if (ans < result)
			ans = result;
	}
	if (!exist(x, y + 1) && valid(x, y + 1))
	{
		int64_t result = sum(x, y + 1);
		// assert(result == calculate(x, y + 1));
		if (ans < result)
			ans = result;
	}
	if (!exist(x, y - 1) && valid(x, y - 1))
	{
		int64_t result = sum(x, y - 1);
		// assert(result == calculate(x, y - 1));
		if (ans < result)
			ans = result;
	}
}

void solve_ac()
{
	point.resize(k);
	for (int i = 0; i < k; i++)
		scanf("%ld %ld", &point[i].x, &point[i].y);
	std::sort(point.begin(), point.end(), cmp);
	init();
	int64_t last = 0;
	int64_t id = 0;
	for (int i = 0; i < k; i++)
		push_vertex(point[i].x, point[i].y);
	if (!exist(1, 1) && valid(1, 1))
	{
		int64_t result = sum(1, 1);
		if (ans < result)
			ans = result;
	}
	if (!exist(1, m) && valid(1, m))
	{
		int64_t result = sum(1, m);
		if (ans < result)
			ans = result;
	}
	if (!exist(n, 1) && valid(n, 1))
	{
		int64_t result = sum(n, 1);
		if (ans < result)
			ans = result;
	}
	if (!exist(n, m) && valid(n, m))
	{
		int64_t result = sum(n, m);
		if (ans < result)
			ans = result;
	}
	printf("%ld", ans);
}

int main()
{
	scanf("%ld %ld %ld", &n, &m, &k);
	solve_ac();
	return 0;
}

最后一个subtask WA了#43~#47,确定是sum()的问题。

我的思路是,sum()函数是计算曼哈顿距离之和的,我先是预处理分段求出x轴绝对值函数kx+b与y轴绝对值函数kx+b,结果跑到#43~#47不知为何sum()似乎算错了,求大佬指出问题。

2023/12/27 23:02
加载中...