【UOJ 129】最大公約數
阿新 • • 發佈:2020-10-26
【題目描述】:
話說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; }