KD-TREE
# Include <queue>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
Using namespace std;
Const int n= 55555, K = 5;
Const int inf = 0x3f3f3f;
# Define sqr (x) * (x)
Int k, n, idx; // k indicates the dimension, and n indicates the number of points.
Struct point
{
Int x [K];
Bool operator <(const point & u) const
{
Return x [idx] <u. x [idx];
}
} Po [N];
Typedef pair <double, point> tp;
Priority_queue <tp> nq;
Struct kdTree
{
Point pt [N <2];
Int son [N <2];
Void build (int l, int r, int rt = 1, int dep = 0)
{
If (l> r) return;
Son [rt] = r-l;
Son [rt * 2] = son [rt * 2 + 1] =-1;
Idx = dep % k;
Int mid = (l + r)/2;
Nth_element (po + l, po + mid, po + r + 1 );
Pt [rt] = po [mid];
Build (l, mid-1, rt * 2, dep + 1 );
Build (mid + 1, r, rt * 2 + 1, dep + 1 );
}
Void query (point p, int m, int rt = 1, int dep = 0)
{
If (son [rt] =-1) return;
Tp nd (0, pt [rt]);
For (int I = 0; I <k; I ++) nd. first + = sqr (nd. second. x [I]-p. x [I]);
Int dim = dep % k, x = rt * 2, y = rt * 2 + 1, fg = 0;
If (p. x [dim]> = pt [rt]. x [dim]) swap (x, y );
If (~ Son [x]) query (p, m, x, dep + 1 );
If (nq. size () <m) nq. push (nd), fg = 1;
Else
{
If (nd. first <nq. top (). first) nq. pop (), nq. push (nd );
If (sqr (p. x [dim]-pt [rt]. x [dim]) <nq. top (). first) fg = 1;
}
If (~ Son [y] & fg) query (p, m, y, dep + 1 );
}
} Kd;
Void print (point & p)
{
For (int j = 0; j <k; j ++) printf ("% d % c", p. x [j], j = K-1? '\ N ':'');
}
Int main ()
{
While (scanf ("% d", & n, & k )! = EOF)
{
For (int I = 0; I <n; I ++) for (int j = 0; j <k; j ++) scanf ("% d ", & po [I]. x [j]);
Kd. build (0, n-1 );
Int t, m;
For (scanf ("% d", & t); t --;)
{
Point ask;
For (int j = 0; j <k; j ++) scanf ("% d", & ask. x [j]);
Scanf ("% d", & m); kd. query (ask, m );
Printf ("the closest % d points are: \ n", m );
Point pt [20];
For (int j = 0 ;! Nq. empty (); j ++) pt [j] = nq. top (). second, nq. pop ();
For (int j = m-1; j> = 0; j --) print (pt [j]);
}
}
Return 0;
}