DZY loves partitioning numbers. He wants to know whether it is possible to partition
n
n into the sum of exactly
k
k distinct positive integers.
After some thinking he finds this problem is Too Simple. So he decides to maximize the product of these k k numbers. Can you help him?
The answer may be large. Please output it modulo 109+7 109+7.
After some thinking he finds this problem is Too Simple. So he decides to maximize the product of these k k numbers. Can you help him?
The answer may be large. Please output it modulo 109+7 109+7.
t t testcases follow. Each testcase contains two positive integers n,k n,k in a line.
( 1≤t≤50,2≤n,k≤109 1≤t≤50,2≤n,k≤109)
4 3 4 3 2 9 3 666666 2
-1
2
24
110888111
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$.
题意:给你个数n,拆k个各不相同的数之和,并且使得k个数的乘积最大,最后输出k个数乘积对1e9+7取模的结果!思路:令sum(a,b),为a + (a + 1) + (a + 2)....+b的结果!先取得的一个数a使得sum(a,a+k-1)刚好小于n,最后多出来的数字加到这一串数后面,每个数加1就行了!通过二分来查找最大的a二分:先对n取半,如果此时sum(a,a+k-1)比n大,则向左找,否则向右找,并且记录最大值MAX如果最后发现MAX 没变的话,则不存在一个a满足式子,则直接输出-1否则就用那个a即可!代码1
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int mod = 1e9+7;
- ll sum(ll a,ll b){
- ll num = b-a+1;
- ll ans;
- ans = num%2 ? (a+b)/2*num : num/2*(a+b);
- return ans;
- }
- int main(){
- int T;
- scanf("%d",&T);
- while(T--){
- ll n,k;
- scanf("%lld%lld",&n,&k);
- ll MAX = -1;
- ll a,l=1,r=n;
- while(l <= r){
- ll mid =(r+l)/2;
- ll tmp = sum(mid,mid+k-1);
- if (tmp > n)r = mid-1;
- if (tmp <= n){
- l = mid + 1;
- if (tmp > MAX){
- MAX = tmp;
- a = mid;
- }
- }
- }
- if (MAX == -1){
- printf("-1\n");
- continue;
- }
- ll tp = n-MAX;
- ll ans = 1;
- for (int i = a; i < a+k; ++i){
- if (i >= a+k-tp)ans=(ans%mod*((i+1)%mod)%mod)%mod;
- else ans = (ans %mod * i%mod)%mod;
- }
- printf("%lld\n",ans);
- }
- return 0;
- }
代码2#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; const int mod = 1e9+7; long long n,k; long long a[maxn]; void solve() { scanf("%lld%lld",&n,&k); if(1ll*(1+k)*k/2>n) { puts("-1"); return; } int l = 1,r = n,ans = 1; while(l<=r) { int mid=(l+r)/2; if(1ll*(mid+mid+k-1)*k/2<=n)l=mid+1,ans=mid; else r=mid-1; } int p = (n-1ll*(ans+ans+k-1)*k/2); for(int i=1;i<=k;i++)a[i]=ans+(i-1); for(int i=k;i>k-p;i--)a[i]++; long long Ans = 1; for(int i=1;i<=k;i++) Ans=(Ans*a[i])%mod; cout<<Ans<<endl; } int main() { int t;scanf("%d",&t); while(t--)solve(); }