Password

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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值