DZY Loves Partition
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 815 Accepted Submission(s): 298
Problem Description
DZY loves partitioning numbers. He wants to know whether it is possible to partition n
into the sum of exactly k
distinct positive integers.
After some thinking he finds this problem is Too Simple. So he decides to maximize the product of these k numbers. Can you help him?
The answer may be large. Please output it modulo 109+7 .
After some thinking he finds this problem is Too Simple. So he decides to maximize the product of these k numbers. Can you help him?
The answer may be large. Please output it modulo 109+7 .
Input
First line contains t
denoting the number of testcases.
t testcases follow. Each testcase contains two positive integers n,k in a line.
(1≤t≤50,2≤n,k≤109 )
t testcases follow. Each testcase contains two positive integers n,k in a line.
(1≤t≤50,2≤n,k≤109 )
Output
For each testcase, if such partition does not exist, please output −1
. Otherwise output the maximum product mudulo 109+7
.
Sample Input
4
3 4
3 2
9 3
666666 2
Sample Output
-1
2
2
4
110888111
Hint
In 1st testcase, there is no valid partition.
In 2nd testcase, the partition is $3=1+2$. Answer is $1 imes 2 = 2$.
In 3rd testcase, the partition is $9=2+3+4$. Answer is $2 imes 3 imes 4 = 24$. Note that $9=3+3+3$ is not a valid partition, because it has repetition.
In 4th testcase, the partition is $666666=333332+333334$. Answer is $333332 imes 333334= 111110888888$. Remember to output it mudulo $10^9 + 7$, which is $110888111$.
Source
题意:t组数据 将n分为k个数的和 使得 这k个数的乘积最大(k个数不能重复) 输出这个数
官方题解
记sum(a,k)=a+(a+1)+⋯+(a+k−1)
首先,有解的充要条件是sum(1,k)≤n(如果没取到等号的话把最后一个k扩大就能得到合法解)。
然后观察最优解的性质,它一定是一段连续数字,或者两段连续数字中间只间隔1个数。这是因为1≤a<=b−2时有ab<(a+1)(b−1)如果没有满足上述条件的话,我们总可以把最左边那段的最右一个数字作为a,最右边那段的最左一个数字作为b,调整使得乘积更大。
可以发现这个条件能够唯一确定n的划分,只要用除法算出唯一的a使得sum(a,k)≤n<sum(a+1,k)就可以得到首项了。
理解我yan代码 先排列一个k位的首项为1 的等差数列 将剩下的数 优先靠右分配

1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<map> 6 using namespace std; 7 #define mod 1000000007 8 #define ll __int64 9 ll T,n,k,f; 10 ll ans = 1; 11 int main() { 12 scanf("%I64d",&T); 13 while(T--) 14 { 15 scanf("%I64d%I64d",&n,&k); 16 ans = 1; 17 if(k==1) 18 { 19 cout<<n<<endl; 20 continue; 21 } 22 if(n<k) 23 cout<<-1<<endl; 24 else 25 { 26 n = n-(1+k)*k/2;//每个只能出现一次 27 if(n<0) 28 { 29 cout<<-1<<endl;continue; 30 } 31 if(n==0) 32 { 33 for(int i=1;i<=k;i++) 34 ans=(ans*i)%mod; 35 cout<<ans<<endl; 36 continue; 37 } 38 for(int i=k;i>k-n%k;i--) 39 ans=(ans*(n/k+1+i))%mod; 40 for(int i=k-n%k;i>=1;i--) 41 ans=(ans*(n/k+i))%mod; 42 cout<<ans<<endl; 43 } 44 } 45 }