CLJ神犇的题目, 其实这题解法并不难, 算是个经典问题解法的简单变形吧, 对于最近点对这个问题, 一般有两种做法, 有一种针对随机数据很快的O(n ^ 2)解法, 还有一种严格O(n * log(n))的分治算法, 对于一般的题目前者会比较快,如果不熟悉这两种做法可以参考http://www.csie.ntnu.edu.tw/~u91029/PointLinePlane2.html 而这道题目的解法其实就是前种解法的变形, 用一个multiset来维护以x为关键字的有序表, 每次插入一个点之前分情况枚举更新答案直到不可能更新。。。。
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
const int N = 500005;
typedef long long LL;
const LL INF = 1LL << 60;
#define DB cout << "Yes" << endl;
#define DB2 cout << "No" << endl;
inline int readint() {
char c = getchar();
while (!isdigit(c)) c = getchar();
int x = 0;
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int buf[10];
inline void writeint(int x) {
int p = 0;
if (x == 0) p++;
else while (x) {
buf[p++] = x % 10;
x /= 10;
}
for (int j = p - 1; j >= 0; j--)
putchar('0' + buf[j]);
}
struct Point {
LL x, y;
bool operator < (const Point& p) const {
return x < p.x;
}
}p[N];
LL dist(const Point& a, const Point& b) {
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
multiset<Point> S;
multiset<Point>::iterator it, tmp;
inline LL pow2(int x) {
return (LL)x * x;
}
int main() {
int test, ax, bx, cx, ay, by, cy, n;
test = readint();
while (test--) {
n = readint(), ax = readint(), bx = readint(), cx = readint();
ay = readint(), by = readint(), cy = readint();
S.clear();
p[0].x = 0, p[0].y = 0;
LL res = 0;
int m;
LL d = INF;
int minX, maxX;
for (int i = 1; i <= n; i++) {
p[i].x = (p[i - 1].x * ax + bx) % cx;
p[i].y = (p[i - 1].y * ay + by) % cy;
if (i == 1) {
S.insert(p[i]);
continue;
}
if (d == 0) break;
minX = S.begin()->x;
it = S.end();
it--;
maxX = it->x;
if (p[i].x <= minX) {
for (it = S.begin(); it != S.end(); it++) {
if (pow2(it->x - p[i].x) >= d) break;
d = min(dist(*it, p[i]), d);
}
}
else if (p[i].x >= maxX) {
while (1) {
if (pow2(it->x - p[i].x) >= d) break;
d = min(dist(*it, p[i]), d);
if (it == S.begin()) break;
it--;
}
}
else {
tmp = S.lower_bound(p[i]);
for (it = tmp; it != S.end(); it++) {
if (pow2(it->x - p[i].x) >= d) break;
d = min(dist(*it, p[i]), d);
}
if (tmp != S.begin()) {
it = tmp;
it--;
while (1) {
if (pow2(it->x - p[i].x) >= d) break;
d = min(dist(*it, p[i]), d);
if (it == S.begin()) break;
it--;
}
}
}
S.insert(p[i]);
res += d;
}
printf("%I64d\n", res);
}
return 0;
}