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): 1444    Accepted Submission(s): 552


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 .
 

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 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 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$.
 

Source



#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int main(void)
{
    long long t, n, k, ans;
    cin >> t;
    while(t--)
    {
        ans = 1;
        scanf("%lld%lld", &n, &k);
        if((1+k)*k/2 > n) puts("-1");
        else
        {
            if(n%k == 0)
            {
                long long avg = (n/k);
                if(k%2) ans = avg;
                for(int i = 1; i <= k/2; i++)
                    ans = ans*(avg-i)*(avg+i)%mod;
            }
            else
            {
                //base, base+1, base+2....base+k-1
                //sum是假设连续,相对第一个数,后面的k-1个数多加的值
                long long sum = (k-1)*k/2;
                //若不连续,num不为0,num的值为需多加的1
                long long num = (n-sum)%k;
                long long base = (n-sum)/k;
                long long i;
                //因为要乘积最大,所以要从后面开始数的num个数加1
                for(i = 1; i <= num; i++)
                    ans = ans*(base+k+1-i)%mod;
                while(i <= k)
                    ans = ans*(base+k-i++)%mod;
            }
            printf("%lld\n", ans);
        }
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值