1. 程式人生 > 實用技巧 >【UOJ 129】最大公約數

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