KDT TLE60 求优化 玄关
查看原帖
KDT TLE60 求优化 玄关
300098
cmaths楼主2023/12/14 12:00

KDT 被卡了,但是正常的 KDT 应该能过除 #13 外所有点

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define fork for(int k = 0; k < K; k++)
#define ll long long

using namespace std;

int read()
{
	int x = 0, f = 1;
	char ch = 0;
	while(!isdigit(ch))
	{
		if(ch == '-')
		{
			f = -1;
		}
		ch = getchar();
	}
	while(isdigit(ch))
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * f;
}

const int N = 100000, K = 2, INF = (int)0x3f3f3f3f3f3f3f3f;
int n, m;

struct Node
{
	int x[K];
}node[N + 5];
Node Mn(Node x, Node y)
{
	for(int k = 0; k < K; k++)
	{
		x.x[k] = min(x.x[k], y.x[k]);
	}
	return x;
}
Node Mx(Node x, Node y)
{
	for(int k = 0; k < K; k++)
	{
		x.x[k] = max(x.x[k], y.x[k]);
	}
	return x;
}
ll dis(Node x, Node y)
{
	ll ret = 0;
	for(int k = 0; k < K; k++)
	{
		ret += ((ll)x.x[k] - y.x[k]) * ((ll)x.x[k] - y.x[k]);
	}
	return ret;
}

void init()
{
	n = read(), m = read();
//	m = (m + 1) >> 1;
	for(int i = 1; i <= n; i++)
	{
		fork
		{
			node[i].x[k] = read();
		}
	}
}

int b[N + 5];
struct Tr
{
	int id;
	int lx, rx;
	Node mn, mx;
	ll gdis(Node t)
	{
		ll ret = 0;
		for(int k = 0; k < K; k++)
		{
			ret += max(((ll)t.x[k] - mn.x[k]) * ((ll)t.x[k] - mn.x[k]), ((ll)t.x[k] - mx.x[k]) * ((ll)t.x[k] - mx.x[k]));
		}
		return ret;
	}
}tr[N + 5];
int rt;
int cntn;
void pushup(int x)
{
	tr[x].mn = tr[x].mx = node[tr[x].id];
	if(tr[x].lx)
	{
		tr[x].mn = Mn(tr[x].mn, tr[tr[x].lx].mn);
	}
	if(tr[x].rx)
	{
		tr[x].mn = Mn(tr[x].mn, tr[tr[x].rx].mn);
	}
	if(tr[x].lx)
	{
		tr[x].mx = Mx(tr[x].mx, tr[tr[x].lx].mx);
	}
	if(tr[x].rx)
	{
		tr[x].mx = Mx(tr[x].mx, tr[tr[x].rx].mx);
	}
}
void build(int &x, int l, int r, int kd)
{
	if(l > r)
	{
		return;
	}
	if(x == 0)
	{
		x = ++cntn;
	}
	nth_element(b + l, b + mid, b + r, [kd](int aa, int bb){return node[aa].x[kd] < node[bb].x[kd];});
	tr[x].id = b[mid];
//	printf("%lld %lld 1111\n", x, tr[x].id);
	build(tr[x].lx, l, mid - 1, (kd + 1) % K);
	build(tr[x].rx, mid + 1, r, (kd + 1) % K);
	pushup(x);
}
struct Dat
{
	ll dis;
	int id;
	bool operator < (const Dat &t) const
	{
		return t.dis < dis;
	}
};
priority_queue <Dat> qu;
void ask(int x, Node t, int k)
{
	if(x == 0)
	{
		return;
	}
	if((int)qu.size() < k || dis(node[tr[x].id], t) > qu.top().dis)
	{
		qu.push({dis(node[tr[x].id], t), tr[x].id});
		if((int)qu.size() > k)
		{
			qu.pop();
		}		
	}
	ll gl = -1, gr = -1;
	if(tr[x].lx)
	{
		gl = tr[tr[x].lx].gdis(t);
	}
	if(tr[x].rx)
	{
		gr = tr[tr[x].rx].gdis(t);
	}
//	if(x == 1)
//	{
//		printf("%f %f 114\n", gl, gr);
//	}
	if(gl > gr)
	{
		if((int)qu.size() < k || ((int)qu.size() == k && gl > qu.top().dis))
		{
			ask(tr[x].lx, t, k);
		}
		if((int)qu.size() < k || ((int)qu.size() == k && gr > qu.top().dis))
		{
			ask(tr[x].rx, t, k);
		}
	}
	else
	{
		if((int)qu.size() < k || ((int)qu.size() == k && gr > qu.top().dis))
		{
			ask(tr[x].rx, t, k);
		}		
		if((int)qu.size() < k || ((int)qu.size() == k && gl > qu.top().dis))
		{
			ask(tr[x].lx, t, k);
		}
	}
}

priority_queue <Dat> ans;
void solve()
{
	for(int i = 1; i <= n; i++)
	{
		b[i] = i;
	}
	build(rt, 1, n, 0);
	for(int i = 1; i <= n; i++)
	{
		ask(rt, node[i], min(m, n));
		while(qu.size())
		{
			ans.push(qu.top());
			if((int)ans.size() > m * 2)
			{
				ans.pop();
			}
			qu.pop();
		}
	}
	printf("%lld", ans.top().dis);
}

signed main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	init();
	solve();
	return 0;
}
2023/12/14 12:00
加载中...