整数拆分并且乘积最大问题

第二次BC,还是被第二题难住了,拆分整数的题

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

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

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

输入描述
第一行t,表示有t组数据。

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

(1≤t≤50,2≤n,k≤10^9)

输出描述
对于每个数据,如果不存在拆分方案,输出−1-1−1;否则输出最大乘积模10^9 + 7

输入样例
4
3 4
3 2
9 3
666666 2

输出样例
-1
2
24
110888111

#include
#include
using namespace std;
const int mod = 1e9 + 7;
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        long long n, k;
        cin >> n >> k;
        if (n <(k*(k + 1)) / 2)
        {
            cout << -1 << endl;
        }
        else
        {
            n = n - k*(k + 1) / 2;
            vector<long long> num(k + 1);
            for (int a = 1;a <= k;a++)
            {
                num[a] = (n / k) + a;
            }
            for (int a = k;a >k - n%k;a--)
            {
                num[a]++;
            }
            long long sum = 1;
            for (int a = 1;a <= k;a++)
            {
                sum = sum*num[a] % mod;
            }
            cout << sum%mod << endl;
        }
    }
    return 0;
}

我的思路是看到拆分成为k个不相等整数,其乘积最大,首先想到的是他们每个数之间的差一定要是最小的,最好是1,而看到k的范围小于19的九次方以后,就要考虑是不是该用long long类型的整形了,在这里卡了我好久,以后需要注意。因为是k个连续的整数是最低要求,起码也要从一开始,因此n一定要大于等于k(k+1)/2才可以,后期要把这个值重新分配给每个数作为权重,因此暂时减掉,所以每个数的基础值的总额现在就是n了,所以再分成k份。现在考虑剩下的余数问题,因为前面的数都是连续的,因此无论加上多少都不对,都会变成重复的数,所以考虑从后面向前加过去。
然后整理一个关于模的运算
(a*b*c*d*e….)%p=(a%p*b)%p*c)%p……
举例:设a=ps+y,b=po+e
(ab)%p=(sop^2+ye+pse+ypo)%p=ye;
(a%p*b)%p=(ypo+ye)%p=ye;
其实是想证明的但是太麻烦了还是举例吧

你可能感兴趣的:(整数拆分并且乘积最大问题)