【UOJ 129】最大公约数

【题目描述】:

话说CD比较欠扁,他表示在课室的日子没有教主在旁边打他的日子太寂寞了,所以这一晚,他终于来到了电脑室被打。由于CD是大家的宠物,于是大家都来打CD了。电脑室里有n个人,第i个人希望打CD ai下。但是太多人打CD,他又会不爽,于是他规定只能有K个人打到他,并且为了公平起见,最终K个人打他的次数都必须是相同的,CD规定这个次数就是这K个人希望打他的次数的最大公约数。为什么是最大公约数呢?因为他觉得被打的次数是GCD的话他才会变成Glad CD。之前说了,CD比较欠扁,于是CD希望,K个人打他的次数的和最大。你能告诉他他最后总共会被打多少下么?

提示:O(n/1+n/2+…+n/n)=O(nlogn)

【输入描述】:

第一行两个正整数n,k。

第二行n个正整数,表示每个人希望打CD多少下。

【输出描述】:

输出一个正整数表示CD会被打多少下。

【样例输入】:

3 1
1 2 3

【样例输出】:

3

【时间限制、数据范围及描述】:

时间:1s 空间:256M

对于30%的数据,保证k<=n<=20。

对于50%的数据,保证输入中所有数小于5,000。

对于100%的数据,保证输入中所有数小于500,000,k<=n。

 

题解:emm数学题看看代码咯

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=500003;
int n,k,a[N],f[N],ans=-1,MX,id=0;
int main(){
    freopen("gcd.in","r",stdin);
    freopen("gcd.out","w",stdout); 
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        for(int j=1;j*j<=a[i];j++){
            if(a[i]%j==0) { f[j]++;  f[a[i]/j]++; }
            if(j==a[i]/j) f[j]--;
        }    
        MX=max(MX,a[i]);
    }
    for(int i=MX;i>=1;i--)
        if(f[i]>=k) { cout<<(ll)((ll)i*(ll)k)<<' '; return 0; } 
    return 0;
}

 

posted @ 2020-10-26 18:46  #Cookies#  阅读(195)  评论(0编辑  收藏  举报