平面 n (≤100,000) 個點,q (≤100,000) 次詢問:給定點 p 和整數 k,求距離 p 第 k 遠的點的編號。距離為歐氏距離平方。
long long dist2(Point a, Point b) {
long long dx = a.x - b.x, dy = a.y - b.y;
return dx*dx + dy*dy;
}
long long maxDist2(KDNode* node, Point p) {
long long d = 0;
d = max(d, dist2(p, {node->x0, node->y0}));
d = max(d, dist2(p, {node->x1, node->y0}));
d = max(d, dist2(p, {node->x1, node->y1}));
d = max(d, dist2(p, {node->x0, node->y1}));
return d;
}
void query(KDNode* node, Point p, int k, priority_queue- & pq) { if (!node) return; long long d = dist2(p, node->pt); Item cur(d, node->pt.id); if (cur < pq.top()) { pq.push(cur); pq.pop(); } // 小頂堆,保持 k 最大 long long dl = node->ch[0] ? maxDist2(node->ch[0], p) : -1; long long dr = node->ch[1] ? maxDist2(node->ch[1], p) : -1; if (dl > dr) { if (dl >= pq.top().dist) query(node->ch[0], p, k, pq); if (dr >= pq.top().dist) query(node->ch[1], p, k, pq); } else { if (dr >= pq.top().dist) query(node->ch[1], p, k, pq); if (dl >= pq.top().dist) query(node->ch[0], p, k, pq); } }
此題是 KD-Tree 解決「第 k 近/遠鄰」的經典應用,堆 + 剪枝 結合優先搜索是核心技巧。