Maximal GCD
題目鏈接:http://codeforces.com/contest/803/problem/C
——每天在線,歡迎留言談論。
題目大意:
給你n,k(1<=n,k<=1e10)。
要你輸出k個數,滿足以下條件:
①這k個數之和等於n
②嚴格遞增
②輸出的 這k個數 的最大公約數q是同樣滿足①②條件中的最大的!
思路:
一、先找出這個符合條件的最大的q:
①q一定是n的 公約數
②q*(1+2+···+k)<=n 時的q就可以成為共約數(因為輸出時 只需要把k增大到m,m滿足 1+2+··+(k-1)+m=n/q 就可以)
③在n的公約數中從大到小遍歷是否符合條件即可。
↓ ↓ ↓ ↓ 不超時的一種 遍歷公約數 的思想!
只需要通過for(long long i=1;i<sqrt(n);i++)來找出最大的那個q
假如2是他的一個約數,那么n/2也是。3是的話n/3也是。所以循環到sqrt(n)即可。最多1e5次循環 不會超T。
二、輸出這k個數
q*a1,q*a2,q*a3 ······ q*ak(沒有,號,只是好看)
其中的{a1,a2,a3···ak}={1,2,3 ··· (k-2) , (k-1) , ((n/q)- sum)}(sum=1+2+···+(k-1))
PS注意:k好大時 long long 也裝不下(1+2+···+k)!(不說太清楚,自己體會,哈哈...)
AC代碼:
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 int main() 5 {//1<=n,k<=1e10 6 long long n,k,sqr,cadd,q;//q為最大公約數 7 cin>>n>>k; 8 if(k>141420) 9 { 10 cout<<"-1"<<endl;return 0; 11 } 12 cadd=(1+k)*k/2;sqr=sqrt(n);q=0; 13 for(long long i=1;i<=sqr;i++) 14 { 15 if(n%i==0) 16 { 17 if(i>=cadd) 18 {q=n/i;break;} 19 else if(n/i>=cadd) 20 q=i; 21 } 22 } 23 //cout<<q<<endl; 24 if(!q) 25 { 26 cout<<"-1"<<endl;return 0; 27 } 28 long long sum=0,i; 29 for(i=1;i<k;i++) 30 { 31 cout<<i*q<<" ";sum+=i; 32 } 33 cout<<q*(n/q-sum)<<endl; 34 return 0; 35 }
2017-05-04 14:06:58 -> 2017-05-05 12:51:05 -> 2017-05-05 20:45:26