hdu5646DZY Loves Partition

问题描述

DZY喜欢拆分数字。他想知道能否把n拆成恰好k个不重复的正整数之和。

思考了一会儿之后他发现这个题太简单,于是他想要最大化这k个正整数的乘积。你能帮帮他吗?

由于答案可能很大,请模10e9+7输出。

输入描述

第一行t,表示有t组数据。

接下来ttt组数据。每组数据包含一行两个正整数n,
,k。

1≤t≤50,2≤n,k≤109

输出描述

对于每个数据,如果不存在拆分方案,输出−1;否则输出最大乘积模10e9+7之后的值。

输入样例

4
3 4
3 2
9 3
666666 2

输出样例

-1
2
24
110888111

Hint

第一组数据没有合法拆分方案。
第二组数据方案为3=1+2,答案为1×2=2
第三组数据方案为9=2+3+4,答案为2×3×4=24。注意9=3+3+3是不合法的拆分方案,因为其中包含了重复数字。
第四组数据方案为666666=333332+333334,答案为333332×333334=110888111。注意要对10e9+7取模后输出,即110888111。

思路:讲N分成K个数,是的K个数的乘积最大。
那么这K个数有两种情况:
1:一串连续的数字,相邻两个数字相差1
2:2串连续的数字,每串数字相邻两个数字相差1,第一串最后一个与第二串第一个相差1,

我们先去找到这个数字串的第一个数。。

这个串可表示为a+1,a+2,a+3……a+k
或者a+1,a+2..a+p-1,a+p+1,a+p+2..a+k

第一种情况很容易。。不说了。。
第二种:1:我们可以二分区插入一个a+p的数,,使得变成第一种情况。。。(别人写的。。窝每写过)
2:假设a+p存在。。。n-(1+k)*k/2后。。理论上temp2少了a+p,,k-temp2%k==p…

#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<stack>
#include<iostream>
using namespace std;
#define mod 1000000007
int main()
{
    int T_T;
    scanf("%d",&T_T);
    while(T_T--){
        long long n,k;
        bool flag=true;
        scanf("%I64d %I64d",&n,&k);

        long long temp1=(1+k)*k/2;
        long long out=1;
        if(temp1>n) flag=false;
        else{
            long long temp2=n-temp1;
            long long temp3=temp2/k;
            long long temp4=temp2%k;

            if(temp4==0){
                for(int i=1;i<=k;i++) out=out*(temp3+i)%mod;
            }
            else{
                for(int i=1;i<=k-temp4;i++) out=out*(temp3+i)%mod;
                for(int i=k-temp4+1;i<=k;i++) out=out*(temp3+i+1)%mod;
            }
        }
        if(flag) printf("%I64d\n",out);
        else printf("-1\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值