【CF583C】【Password】【数论】

56 篇文章 0 订阅

题目大意

有n个数,给出他们两两的gcd(包括自己和自己)n^2个,求这n个数。

解题思路

显然发现最大的那个gcd一定是最大的数,第二大的gcd一定是第二大的数,出去它们gcd的影响,最大的哪一个一定是第三大。以此类推用数据结构存储即可。
可是我想到了一个随机数据下表现优良的水法。大量的实验证明随机数据下不同的gcd大约在1.5n左右,gcd是原数的约数,若有x个gcd是y或y的倍数,则有
x
个数是y或y的倍数。所以可以用
(1.5n)2
的复杂度计算影响。

code

#include<set>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
int const maxn=1000,maxa=1000000000;
int n,a[maxn*maxn+10],b[maxn*maxn+10],cnt[maxn*maxn+10],num[maxn*maxn+10];
int main(){
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%d",&n);
    fo(i,1,n*n)scanf("%d",&a[i]);
    sort(a+1,a+n*n+1);
    fo(i,1,n*n)
        if(a[i]!=a[i-1])b[++b[0]]=a[i],cnt[b[0]]=1;
        else cnt[b[0]]++;
    fd(i,b[0],1){
        int cntt=0,numm=0;
        fo(j,i,b[0])
            if(b[j]%b[i]==0)cntt+=cnt[j],numm+=num[j];
        num[i]=sqrt(cntt)-numm;
        fo(j,1,num[i])printf("%d ",b[i]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值