#include #include #include #include #include #define REP(i,a,b) for(i=a;ik);if(i>=j)break;t=d[i];d[i]=d[j];d[j]=t;}intSort(d,i);intSort(d+j+1,s-j-1);} int N; int F[100001]; int F_MAX; int S[100001]; int Finv[100001]; /* Finv[F[i]]= i */ int chked[100001]; /* cheked[i]=1 if F[i] is used for AP */ int rest[100001], rest_size; /* unused elements in AP (F[rest[0]], ..., F[rest[rest_size-1]] are unused in AP */ int memo[100001], memo_size; int solve(void){ /* searching GP using all unused elements in AP */ int i, j, k; double r, now; int nowi; int br; /* store unused elements in AP */ rest_size = 0; rep(i,N) if(chked[i]==0) rest[rest_size++] = i; /* The number of unused elements <= 1, then the trivial solution exists */ if(rest_size<=1){ br = 0; rep(i,N) if(chked[i]) { if(!br) br=1; else putchar(' '); printf("%d",F[i]); } puts(""); if(rest_size==0) printf("%d %d\n",F[0],F[1]); if(rest_size==1 && rest[0] == 0) printf("%d %d\n",F[0],F[1]); if(rest_size==1 && rest[0] != 0) printf("%d %d\n",F[0],F[rest[0]]); return 1; } i = rest[0]; /* the first elements of GP should be F[rest[0]] */ REP(j,i+1,N){ /* brute-force for the second elements F[j] of GP */ r = F[j] / (double) F[i]; /* ratio */ memo_size = 1; memo[0] = i; k = 1; now = F[i]; for(;;){ now *= r; nowi = (int)(now + 0.5); if(nowi < now-EPS || nowi > now+EPS) break; if(nowi > F_MAX || Finv[nowi]==-1) break; memo[memo_size++] = Finv[nowi]; if(rest[k] < Finv[nowi]) break; if(rest[k] == Finv[nowi]) k++; if(k==rest_size){ /* all unused elements are used now:) */ br = 0; rep(i,N) if(chked[i]) { if(!br) br=1; else putchar(' '); printf("%d",F[i]); } puts(""); br = 0; rep(i,memo_size){ if(!br) br=1; else putchar(' '); printf("%d",F[memo[i]]); } puts(""); return 1; } } } /* not found */ return 0; } int main(){ int T; int i, j, k; int d; int solved; int mx_cnt, bef, cnt; assert( scanf("%d",&T)==1 ); assert( 0<=T && T<=100 ); while(T--){ assert( scanf("%d",&N)==1 ); assert( 2<=N && N<=10000 ); rep(i,N) assert( scanf("%d",F+i)==1 ), assert( 1<=F[i] && F[i]<=M_MAX ); REP(i,1,N) assert( F[i-1] < F[i] ); F_MAX = F[N-1]; rep(i,F_MAX+1) Finv[i] = -1; rep(i,N) Finv[F[i]] = i; solved = 0; if(N < 50){ /* N is small -> brute-force for searching AP */ rep(i,N) REP(j,i+1,N) if(!solved) { /* The first and second elements of AP are F[i] and F[j] */ rep(k,N) chked[k] = 0; for(k=F[i];k<=F_MAX;k+=F[j]-F[i]){ /* AP should be chosen as the longestg one */ if(Finv[k]==-1) break; chked[Finv[k]] = 1; } solved = solve(); } } else { /* N is large, so almost elements should be belong to AP */ rep(i,N-1) S[i] = F[i+1] - F[i]; intSort(S, N-1); mx_cnt = 0; bef = -1; cnt = 0; rep(i,N-1){ if(bef!=S[i]) cnt = 0; bef = S[i]; cnt++; if(mx_cnt < cnt) mx_cnt = cnt, d = bef; /* difference d should be most frequent elements in S[i] = F[i+1] - S[i] */ } /* calculate the number S[i] of elements of AP stating F[i] (difference is d) */ /* AP should be chosen as the longest one */ for(i=N-1;i>=0;i--){ S[i] = 1; if(F[i]+d <= F_MAX && Finv[F[i]+d] >= 0) S[i] = S[Finv[F[i]+d]] + 1; } k = 0; rep(i,N) if(S[i] > S[k]) k = i; /* AP should start at F[k] */ rep(i,N) chked[i] = 0; for(k=F[k];k<=F_MAX;k+=d){ if(Finv[k]==-1) break; chked[Finv[k]] = 1; } solved = solve(); /* find GP */ } assert( solved ); } return 0; }