社区讨论

一个小细节差了10倍时间

P4169[Violet] 天使玩偶/SJY摆棋子参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo37b85u
此快照首次捕获于
2023/10/24 01:58
2 年前
此快照最后确认于
2023/10/24 01:58
2 年前
查看原帖
这是原码
C
#include<bits/stdc++.h>
using namespace std;
int dan = 0x7fffffff, n, m, wd, tt, rt, c[5000001], cc;
double aa = 0.66;
struct zyx {
	int x[3];
}a[5000001];
struct lbf {
	int minn[3], maxx[3], l, r, s;
	zyx x;
}t[5000001];
bool operator<(zyx a, zyx b)
{
	return a.x[wd] < b.x[wd];
}
void bs(int u)
{
	int ll, rr;
	ll = t[u].l;
	rr = t[u].r;
	for (int i = 1; i <= 2; i++)
	{
		t[u].minn[i] = t[u].maxx[i] = t[u].x.x[i];
		if (ll)
			t[u].minn[i] = min(t[u].minn[i], t[ll].minn[i]), t[u].maxx[i] = max(t[u].maxx[i], t[ll].maxx[i]);
		if (rr)
			t[u].minn[i] = min(t[u].minn[i], t[rr].minn[i]), t[u].maxx[i] = max(t[u].maxx[i], t[rr].maxx[i]);
	}
	t[u].s = t[ll].s + t[rr].s + 1;
}
int js(int l,int r,int ww)
{
	if (l > r)
		return 0;
	int mid, x;
	mid = (l + r) >> 1;
	wd = ww;
	x = ++tt;
	nth_element(a + l, a + mid, a + r + 1);
	t[x].x = a[mid];
	t[x].l = js(l, mid - 1, ww ^ 1);
	t[x].r = js(mid + 1, r, ww ^ 1);
	bs(x);
	return x;
}
int cj(int l, int r, int ww)
{
	if (l > r)
		return 0;
	int mid, x;
	mid = (l + r) >> 1;
	wd = ww;
	x = c[cc--];
	nth_element(a + l, a + mid, a + r + 1);
	t[x].x = a[mid];
	t[x].l = js(l, mid - 1, ww ^ 1);
	t[x].r = js(mid + 1, r, ww ^ 1);
	bs(x);
	return x;
}
void pia(int u, int num)
{
	if (t[u].l)pia(t[u].l, num);
	a[num + t[t[u].l].s + 1] = t[u].x;
	c[++cc] = u;
	if (t[u].r)pia(t[u].r, num + t[t[u].l].s + 1);
}
void cz(int &u, int ww)
{
	if (t[u].s * aa < t[t[u].l].s || t[u].s * aa < t[t[u].r].s)
		pia(u, 0), u = cj(1, t[u].s, ww);
}
void cr(zyx x, int &u, int ww)
{
	if (!u)
	{
		u = ++tt;
		t[u].l = t[u].r = 0;
		t[u].x = x;
		bs(u);
		return;
	}
	if (x.x[ww] < t[u].x.x[ww])
		cr(x, t[u].l, ww ^ 1);
	else
		cr(x, t[u].r, ww ^ 1);
	bs(u);
	cz(u, ww);
}
int lj(zyx d, int u)
{
	int ans = 0;
	for (int i = 1; i <= 2; i++)
		ans += max(0, d.x[i] - t[u].maxx[i]) + max(0, t[u].minn[i] - d.x[i]);
	return ans;
}
int jl(zyx a, zyx b)
{
	return abs(a.x[1] - b.x[1]) + abs(a.x[2] - b.x[2]);
}
void dann(zyx d, int u)
{
	dan = min(dan, jl(d, t[u].x));
	int a, b;
	a = b = 0x7fffffff;
	if (t[u].l)a = lj(d, t[u].l);
	if (t[u].r)b = lj(d, t[u].r);
	if (a < b)
	{
		if (a < dan)dann(d, t[u].l);
		if (b < dan)dann(d, t[u].r);
	}
	else
	{
		if (b < dan)dann(d, t[u].r);
		if (a < dan)dann(d, t[u].l);
	}
}
int main()
{
	zyx d;
	int x;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &a[i].x[1], &a[i].x[2]);
	rt=js(1,n,0);
	for(int i=1; i<=m; i++)
	{
		scanf("%d%d%d", &x, &d.x[1], &d.x[2]);
		if (x == 1)
			cr(d, rt, 0);
		else
		{
			dan = 0x7fffffff;
			dann(d, rt);
			printf("%d\n", dan);
		}
	}
	return 0;
}
C
struct zyx {
	int x[3];
}a[5000001];
struct lbf {
	int minn[3], maxx[3], l, r, s;
	zyx x;
}t[5000001];
这里的x,minn,maxx下标都是从1开始的 1~2 但改成0~1,下标从0开始, 时间却少了10倍, 蒟蒻调了一晚上才查出来是这个 (出题人你mu是批发的吧)

回复

2 条回复,欢迎继续交流。

正在加载回复...