您的位置:首页 > 其它

HDOJ 5646 DZY Loves Partition

2016-03-19 21:33 302 查看

DZY Loves Partition

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 117 Accepted Submission(s): 38



[align=left]Problem Description[/align]
DZY loves partitioning numbers. He wants to know whether it is possible to partitionn
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 thesek
numbers. Can you help him?

The answer may be large. Please output it modulo 109+7.

[align=left]Input[/align]
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)

[align=left]Output[/align]
For each testcase, if such partition does not exist, please output−1.
Otherwise output the maximum product mudulo 109+7.

[align=left]Sample Input[/align]

4
3 4
3 2
9 3
666666 2


[align=left]Sample Output[/align]

-1
2
24
110888111

Hint
In 1st testcase, there is no valid partition.
In 2nd testcase, the partition is $3=1+2$. Answer is $1\times 2 = 2$.
In 3rd testcase, the partition is $9=2+3+4$. Answer is $2\times 3 \times 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\times 333334= 111110888888$. Remember to output it mudulo $10^9 + 7$, which is $110888111$.


#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define MOD 1000000007
using namespace std;

int main()
{
int t,i;
__int64 s,n,k;
scanf("%d",&t);
while(t--)
{
s=1;
scanf("%I64d%I64d",&n,&k);
if(n<k*(k+1)/2)
{
printf("-1\n");
continue;
}
if(n%k==0)
{
int tem=n/k;
if(k&1)
s=tem;//这里竟然写成k。。。。我真是个。。。。
for(i=1;i<=k/2;++i)
s=s*(tem-i)*(tem+i)%MOD;
}
else
{
int tem=k*(k-1)/2;//这里将第一个数看做基数,这里加和的是之后的k-1个数在基数上的增量(这里先将这k个数看为连续的)
int num=(n-tem)%k;//将这些增量都减去再取余就得到若是这k个数如此取加和之后与n的差量(需将这些差量补充到k个数中)
int base=(n-tem)/k;//求基数。因为要求乘积最大所以这些增量需要一个一个的加到后num个数上)
i=1;
for(;i<=num;++i)
{
s=s*(base+k-i+1)%MOD;//这里就是要加1的乘积
}
while(i<=k)
s=s*(base+k-i++)%MOD;//不加1的乘积
}
printf("%I64d\n",s);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: