1 /*将x从小到大排序,每次插入一个点,直接找比这个点的x大的第一个,然后从这个开始向两边找
2 ,找点的下标用多重容器实现*/
3 #include<stdio.h>
4 #include<string.h>
5 #include<algorithm>
6 #include<set>
7 #include<algorithm>
8 #include<iostream>
9 using namespace std;
10 struct point
11 {
12 __int64 x,y;
13 bool operator<(const point &a) const
14 {
15 return x<a.x;
16 }
17 };
18 void cacl(__int64 n,__int64 x[])
19 {
20 __int64 a,b,c;
21 scanf("%I64d%I64d%I64d",&a,&b,&c);
22 int i;
23 x[0]=0;
24 for(i=1;i<=n;i++)
25 x[i]=(x[i-1]*a+b)%c;
26 }
27 __int64 min(__int64 a,__int64 b)
28 {
29 if(a<b) return a;
30 return b;
31 }
32 __int64 x[500005],y[500005],n;
33 void find()
34 {
35 __int64 i,j;
36 __int64 ans,sum;
37 __int64 m1,m2;
38 scanf("%I64d",&n);
39 cacl(n,x);
40 cacl(n,y);
41 //for(i=1;i<=n;i++)
42 // printf("%I64d %I64d\n",x[i],y[i]);
43 ans=(__int64)1<<60;
44 sum=0;
45 multiset<point> M;
46 for(i=1;i<=n;i++)
47 {
48 point p;
49 p.x=x[i]; p.y=y[i];
50
51 if(i>1)//从第二个点开始
52 {
53 multiset<point>::iterator it=M.lower_bound(p),e;
54 for(e=it;e!=M.end();e++)
55 {
56 m1=e->x-p.x;////差值
57 if(m1*m1>=ans) break;
58 m2=e->y-p.y;
59 ans=min(ans,m1*m1+m2*m2);
60 }
61 for(e=it;e!=M.begin();)
62 {
63 e--;//防止重复,上面已经找过it了
64 m1=e->x-p.x;
65 if(m1*m1>=ans) break;
66 m2=e->y-p.y;
67 ans=ans=min(ans,m1*m1+m2*m2);
68 }
69 sum=sum+ans;
70 }
71 M.insert(p);
72 }
73 printf("%I64d\n",sum);
74 }
75 int main()
76 {
77 int t;
78 scanf("%d",&t);
79 while(t--)
80 {
81 find();
82 }
83 return 0;
84 }