Password
题目大意
请你求出密码序列
B
。
数据范围
题解
这一题比较好玩,如果想得出来,就很简单,否则就很难。
首先将
现在我们考虑
Ans3
,
Ans3
是否就是第三大呢?
我们知道,可能比
Ans3
大的也就只有gcd(
Ans1
,
Ans2
)了。
那我们在找
Ans3
之前把2个gcd(
Ans1
,
Ans2
)从
A
序列中去掉就行了。
同理,我们找到
去掉操作可以用哈希来维护。
Code(Pascal)
const
mo=1000007;
var
n,m,j,k,l,i,o,p:longint;
ans:array[0..2000] of longint;
ha:array[0..1000007,1..2] of int64;
a:array[0..2000000] of int64;
procedure qsort(l,r:longint);
var
i,j:longint;
m:int64;
begin
i:=l;
j:=r;
m:=a[(l+r) div 2];
repeat
while a[i]>m do inc(i);
while a[j]<m do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
function gcd(a,b:int64):int64;
var
t:int64;
begin
t:=0;
repeat
t:=a mod b;
a:=b;
b:=t;
until t=0;
exit(a);
end;
procedure zj(o:longint);
var
m:longint;
begin
m:=o mod mo;
while (ha[m,1]<>0) and (ha[m,1]<>o) do
m:=(m+1) mod mo;
ha[m,1]:=o;
inc(ha[m,2],2);
end;
function ok(o:longint):boolean;
var
m:longint;
begin
m:=o mod mo;
while (ha[m,1]<>0) and (ha[m,1]<>o) do
m:=(m+1) mod mo;
ha[m,1]:=o;
if ha[m,2]=0 then exit(true);
dec(ha[m,2]);
exit(false);
end;
begin
readln(n);
for i:=1 to n*n do
read(a[i]);
qsort(1,n*n);
ans[1]:=a[1];
ans[2]:=a[2];
zj(gcd(ans[1],ans[2]));
k:=2;
for i:=3 to n*n do
if ok(a[i]) then
begin
inc(k);
ans[k]:=a[i];
for l:=1 to k-1 do
zj(gcd(ans[l],ans[k]));
end;
for i:=1 to n do
write(ans[i],' ');
end.