【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     

 

posted on 2018-11-18 22:13  myx12345  阅读(129)  评论(0编辑  收藏  举报

导航