HDOJ 5646 DZY Loves Partition

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


Problem Description
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.
 

Input
First line contains t denoting the number of testcases.

t testcases follow. Each testcase contains two positive integers n,k in a line.

(1t50,2n,k109)
 

Output
For each testcase, if such partition does not exist, please output1. Otherwise output the maximum product mudulo 109+7.
 

Sample Input
4 3 4 3 2 9 3 666666 2
 

Sample Output
-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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值