解:若sum(1,k)已经大于n则必无解,否则可通过对最大数增加一定能得到解。
当有解时:由基本不等式的(a1+a2+...+an)*1/n>=(a1*a2...*an)^1/n.挡a1,a2...相等时取等号,要使乘积尽可能大,那么需要这n个数尽可能接近,于是求连续最大和sum(begin,begin+k-1)<=n,然后把n-sum(begin.begin+k-1)剩下的从大到小分配即可。
AC代码:
//************************************************************************// //*Author : Handsome How *// //************************************************************************// //#pragma comment(linker, "/STA CK:1024000000,1024000000") #pragma warning(disable:4996) #include <vector> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <algorithm> #include <sstream> #include <iostream> #include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #include <ctime> #include <cassert> #if defined(_MSC_VER) || __cplusplus > 199711L #define aut(r,v) auto r = (v) #else #define aut(r,v) __typeof(v) r = (v) #endif #define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it) #define fur(i,a,b) for(int i=(a);i<=(b);i++) #define furr(i,a,b) for(int i=(a);i>=(b);i--) #define cl(a) memset((a),0,sizeof(a)) using namespace std; typedef long long LL; //---------------------------------------------------- const LL mod = 1e9 + 7; int main() { //freopen("E:\\data.in", "r", stdin); ios :: sync_with_stdio(false); int T; scanf("%d", &T); while (T--) { LL n, k; scanf("%I64d%I64d", &n, &k); LL t; t = (1 + k)*k / 2; if(t>n) { printf("-1\n"); continue; } LL begin; begin = (2 * n / k + 1 - k) / 2; LL res =n - (begin + begin + k - 1)*k / 2; LL real = 1; LL end = begin + k - 1; while (res) { real *= (end + 1); real %= mod; res--; end--; } for (LL i = begin; i <= end; i++) { real *= i; real %= mod; } printf("%I64d\n",real); } return 0; }