Language: C++

#include "bits/stdc++.h"
using namespace std;
using ld =long double;
const ld eps = 1e-15;

ld getdis(vector<ld>&l, vector<ld>&r) {
	ld sum = 0;
	for (int i = 0; i < 3; ++i) {
		sum += (l[i] - r[i])*(l[i] - r[i]);
	}
	return sqrt(sum);
}

struct po {
	int index;
	vector<ld> coors;
	po(int _d):coors(_d) {
		index = -1;
	}
	po(int _index, vector<ld>_coors) :index(_index), coors(_coors) {

	}
};
ld getdis(po&lpo, po&rpo) {
	return getdis(lpo.coors, rpo.coors);
}
template<class T>
class axisSorter {
	int k;
public:
	axisSorter(int _k) : k(_k) {}
	bool operator()(const T &a, const T &b) {
		return a.coors[k] < b.coors[k];
	}
};


struct Ans {
	ld dis;
	pair<int, int>p;
	
};


bool operator<(const Ans&l, const Ans&r) {
	if (abs(l.dis - r.dis) < eps) {
		assert(l.p.first < l.p.second);
		assert(r.p.first < r.p.second);
		return l.p < r.p;
	}
	else {
		return l.dis < r.dis;
	}
	return true;
}
Ans answer;

template<class T, int Dim = 3>
struct kdtree {
public:
	T midpo;
	vector<T>pos;
	kdtree<T> *ltree, *rtree;
	int depth;
	int axis;
	kdtree(const T &p_) :midpo(p_), ltree(nullptr), rtree(nullptr) {

	}
	~kdtree() {
		if(ltree!=nullptr)	delete(ltree);
	
		if(rtree!=nullptr)delete(rtree);
	}

	kdtree(vector<T>&ps_, const int& l, const int& r, const int depth_ = 0) : ltree(nullptr), rtree(nullptr), depth(depth_), axis(depth%Dim) {
		init(ps_, l, r);
	}
	void getmindis() {
		vector<po>lpos,rpos;
		ld axisvalue = midpo.coors[axis];
		for (auto& po : pos) {
			if (po.index == midpo.index)continue;
			if (axisvalue>po.coors[axis]-eps*10000&&po.coors[axis]>axisvalue - sqrt(answer.dis)-eps * 10000) {
				lpos.emplace_back(po);
			}
			else if (axisvalue<po.coors[axis]+eps * 10000 &&po.coors[axis] < axisvalue + sqrt(answer.dis)+eps * 10000) {
				rpos.emplace_back(po);
			}
		}
		for (auto& lpo : lpos) {
			for (auto& rpo : rpos) {
				ld dis = getdis(lpo, rpo);
				pair<int, int> p(rpo.index, lpo.index);
				if (p.first > p.second)swap(p.first, p.second);
				Ans nans{ dis,p };

				answer = min(answer, nans);
			}
			{
				ld dis = getdis(lpo, midpo);
				pair<int, int> p(midpo.index, lpo.index);
				if (p.first > p.second)swap(p.first, p.second);
				Ans nans{ dis,p };
				answer = min(answer, nans);
			}
		}
		for (auto& rpo : rpos) {
			ld dis = getdis(midpo, rpo);
			pair<int,int> p(midpo.index, rpo.index);
			if (p.first > p.second)swap(p.first, p.second);
			Ans nans{ dis,p };
			answer = min(answer, nans);
			int b;
			b = 1; b++;
		}
		
		
	}
private:
	void init(vector<T>&ps, const int& l, const int& r) {
		if (l >= r) {
			return;
		}
		sort(ps.begin() + l, ps.begin() + r, axisSorter<T>(axis));
		const int mid = (l + r) / 2;
		midpo = ps[mid];
		pos = vector<T>(ps.begin() + l, ps.begin() + r);
		
		ltree = make_kdtree(ps, l, mid, depth + 1);
		if (ltree != nullptr) {
			ltree->getmindis();
			ltree->pos.clear();
			if (ltree->rtree) {
				delete(ltree->rtree);
				ltree->rtree = nullptr;
			}
			if (ltree->ltree) {
				delete(ltree->ltree);
				ltree->ltree = nullptr;
			}
		}
		rtree = make_kdtree(ps, mid + 1, r, depth + 1);
		if (rtree != nullptr) {
			rtree->getmindis();
			rtree->pos.clear(); 
			if (rtree->rtree) {
				delete(rtree->rtree);
				rtree->rtree = nullptr;
			}
			if (ltree->rtree) {
				delete(rtree->ltree);
				ltree->rtree = nullptr;
			}
		}
	}
};


//[l..r)
template<class T>
kdtree<T> *make_kdtree(vector<T>&ps_, const int& l, const int& r, const int& depth = 0) {
	if (l >= r)return nullptr;
	else {
		return new kdtree<T>(ps_, l, r, depth);
	}
}

vector<ld>getunit(vector<int>v) {
	vector<ld>unit;
	ld len = 0;
	for (auto a : v) {
		len += a*a;
		unit.emplace_back(ld(a));
	}
	len = sqrt(len);
	for (auto&u : unit) {
		u /= len;
	}
	return unit;
}
int gcd( int l, int r) {
	assert(l > 0 && r > 0);
	if (l > r)return gcd(r, l);
	else {
		const  int num = r%l;
		if (num) {
			return gcd(l, num);
		}
		else {
			return l;
		}
	}
}
int gcd(vector<int>nums) {
	if (nums.size() == 1)return nums[0];
	 int num = nums[0];

	for (int i = 1; i < nums.size(); ++i) {
		num = gcd(num, nums[i]);
	}
	return num;
}

int main() {
	while (1) {
		answer = Ans{ 1e18,make_pair(-1,-1) };
		int M, N, S, W; cin >> M >> N >> S >> W;
		if (!M&&!N&&!S&&!W)break;
		vector<po>pos;
		vector<vector<int>>memo;
		{
			{
				int nx, ny, nz;
				for (int i = 0; i < M; ++i) {
					cin >> nx >> ny >> nz;
					memo.push_back(vector<int>{nx, ny, nz});
				}
				int g = S;
				for (int i = M; i < M + N; ++i) {
					nx = (g / 7) % 100 + 1;
					ny = (g / 700) % 100 + 1;
					nz = (g / 70000) % 100 + 1;
					memo.push_back(vector<int>{nx, ny, nz});
					if (g % 2 == 0)g = g / 2;
					else g = (g / 2) ^ W;
				}
			}
			sort(memo.begin(), memo.end(), [](const vector<int>&l, const vector<int>&r) {
				for (int i = 0; i < 3; ++i) {
					if (l[i] == r[i])continue;
					else return l[i] < r[i];
				}
				return false;
			});
			{
				vector<vector<int>>newmemo;
				map<vector<int>,int>amap;
				for (int i = 0; i < memo.size(); ++i) {
					int agcd = gcd(memo[i]);
					vector<int>v(3);
					for (int j = 0; j < 3; ++j)v[j] = memo[i][j] / agcd;
					if (amap.find(v)==amap.end()||amap[v] > agcd) {
						amap[v] = agcd;
					}
				}
				for (auto m : amap) {
					auto v = m.first;
					for (int i = 0; i < 3; ++i) {
						v[i] *= m.second;
					}
					newmemo.emplace_back(v);
				}
				memo = newmemo;
			}
			sort(memo.begin(), memo.end(), [](const vector<int>&l, const vector<int>&r) {
				for (int i = 0; i < 3; ++i) {
					if (l[i] == r[i])continue;
					else return l[i] < r[i];
				}
				return false;
			});
			for (int i = 0; i < memo.size(); ++i) {
				po p(i, getunit(memo[i]));
				pos.emplace_back(p);
			}
		}
		
		auto tree = make_kdtree(pos, 0, pos.size(), 0);
		tree->getmindis();
		auto ansp = answer;
		if (ansp.p.first >ansp.p.second)swap(ansp.p.first, ansp.p.second);
		for (int i = 0; i < 3; ++i) {
			cout << memo[answer.p.first][i] << " ";
		}
		for (int i = 0; i < 3; ++i) {
			cout << memo[answer.p.second][i];
			if (i == 2)cout << endl;
			else cout << " ";
		}
		delete(tree);
	}
	return 0;
}
//1524,2763

Compiler output:
a.cc: In instantiation of 'kdtree<T, Dim>::kdtree(std::vector<_Tp>&, const int&, const int&, int) [with T = po; int Dim = 3]':
a.cc:164:10:   required from 'kdtree<T>* make_kdtree(std::vector<_Tp>&, const int&, const int&, const int&) [with T = po]'
  164 |                 return new kdtree<T>(ps_, l, r, depth);
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:268:26:   required from here
  268 |                 auto tree = make_kdtree(pos, 0, pos.size(), 0);
      |                             ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
a.cc:75:144: error: no matching function for call to 'po::po()'
   75 |         kdtree(vector<T>&ps_, const int& l, const int& r, const int depth_ = 0) : ltree(nullptr), rtree(nullptr), depth(depth_), axis(depth%Dim) {
      |                                                                                                                                                ^
a.cc:20:9: note: candidate: 'po::po(int, std::vector<long double>)'
   20 |         po(int _index, vector<ld>_coors) :index(_index), coors(_coors) {
      |         ^~
a.cc:20:9: note:   candidate expects 2 arguments, 0 provided
a.cc:17:9: note: candidate: 'po::po(int)'
   17 |         po(int _d):coors(_d) {
      |         ^~
a.cc:17:9: note:   candidate expects 1 argument, 0 provided
a.cc:14:8: note: candidate: 'po::po(const po&)'
   14 | struct po {
      |        ^~
a.cc:14:8: note:   candidate expects 1 argument, 0 provided
a.cc:14:8: note: candidate: 'po::po(po&&)'
a.cc:14:8: note:   candidate expects 1 argument, 0 provided