【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; }