Description
Solution
首先因为转化成一个矩阵后,发现除了对角线的值可能会使奇数以外,其他都为偶数,所以出现次数为奇数的,一定出现在答案队列里,剔除这些数相互的gcd后,可能还有剩下的一些偶数。因为gcd(a,b)<=min(a,b),所以剩余的数中,最大的也会是答案,把该数以及与存在于答案队列的数所取gcd剔除后,重复以上操作,直到剩余的数为0。
Code
const mo=1000007;
var
h,z:array[1..mo] of longint;
t:array[0..1000000] of longint;
a,s:array[0..100000] of longint;
i,j,sum,ans,n,tot,num,wz:longint;
function gcd(x,y:longint):longint;
begin
gcd:=0;
while x mod y<>0 do
begin
gcd:=x mod y;
x:=y;
y:=gcd;
end;
exit(y);
end;
procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
i:=l;j:=r;
mid:=t[(l+r)div 2];
repeat
while t[i]>mid do inc(i);
while mid>t[j] do dec(j);
if i<=j then
begin
tot:=t[i];t[i]:=t[j];t[j]:=tot;
inc(i); dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure deal;
var i,j:longint;
begin
for i:=1 to sum do
if s[i] mod 2=1 then
begin
inc(ans);
t[ans]:=a[i];
dec(s[i]);
for j:=1 to ans-1 do
begin
tot:=gcd(t[j],a[i]);
wz:=(tot-1)mod mo+1;
while z[wz]<>tot do wz:=wz mod mo+1;
dec(s[h[wz]],2);
end;
end;
end;
begin
readln(n);
for i:=0 to n-1 do
for j:=0 to n-1 do read(t[i*n+j]);
qsort(0,n*n-1);
a[1]:=t[0];s[1]:=1;sum:=1;
wz:=(t[i]-1)mod mo+1;
h[wz]:=1;z[wz]:=t[1];
for i:=1 to n*n-1 do
begin
if t[i]<>t[i-1] then
begin
inc(sum);
a[sum]:=t[i];
wz:=(t[i]-1) mod mo+1;
while h[wz]<>0 do wz:=wz mod mo+1;
h[wz]:=sum;
z[wz]:=t[i];
end;
inc(s[sum]);
end;
fillchar(t,sizeof(t),0);
ans:=0; num:=-1;
while ans<n do
begin
num:=ans;
deal;
if (num=ans)and(ans<n) then
begin
for i:=1 to sum do
if s[i]>0 then break;
inc(ans);
t[ans]:=a[i];
dec(s[i]);
for j:=1 to ans-1 do
begin
tot:=gcd(t[j],a[i]);
wz:=(tot-1)mod mo+1;
while z[wz]<>tot do wz:=wz mod mo+1;
dec(s[h[wz]],2);
end;
end;
end;
qsort(1,ans);
for i:=1 to ans do write(t[i],' ');
writeln;
end.