1. 程式人生 > >【HDOJ5976】Detachment(貪心)

【HDOJ5976】Detachment(貪心)

題意:給定n,要求構造若干個各不相同且和為n的正整數使得它們的乘積最大

T<=1e6,1<=n<=1e9

思路:From https://blog.csdn.net/qq_34374664/article/details/53466435

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 typedef long long ll;
 7 using
namespace std; 8 #define N 110000 9 #define oo 10000000 10 #define MOD 1000000007 11 12 ll fac[N],inv[N],exf[N],sum[N]; 13 14 int main() 15 { 16 int cas; 17 scanf("%d",&cas); 18 fac[0]=fac[1]=inv[0]=inv[1]=exf[0]=exf[1]=1; 19 sum[1]=0; 20 for(int i=2;i<N;i++) 21 { 22 fac[i]=fac[i-1
]*i%MOD; 23 inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD; 24 exf[i]=exf[i-1]*inv[i]%MOD; 25 sum[i]=sum[i-1]+i; 26 } 27 while(cas--) 28 { 29 ll n; 30 scanf("%I64d",&n); 31 if(n==1) 32 { 33 printf("1\n"); 34 continue;
35 } 36 int l=2; 37 int r=N-1; 38 int last=2; 39 while(l<=r) 40 { 41 int mid=(l+r)>>1; 42 if(sum[mid]<=n){last=mid; l=mid+1;} 43 else r=mid-1; 44 } 45 int res=n-sum[last]; 46 ll ans=0; 47 if(res==last) ans=fac[last]*inv[2]%MOD*(res+2)%MOD; //全部+1,剩下的1加在最後一個數上 48 else ans=fac[last+1]*exf[last+1-res]%MOD*fac[last-res]%MOD; //從後往前+1 49 printf("%I64d\n",ans); 50 } 51 return 0; 52 } 53