2016年ICPC亚洲区域赛大连站F题Detachment

题目链接https://ac.nowcoder.com/acm/problem/124645

题意简介:

  把给定的数x,拆成若干个不相等的数相加,x = a1 + a2 + ...,使得这些不相等的数的乘积s = a1 * a2 * ...最大,求最大的s

解题思路:

  参考自https://www.cnblogs.com/ymzjj/p/9865052.html

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 1e5 + 5;
 5 const int mod = 1e9 + 7;
 6 ll mul[N]; //前缀积 
 7 ll sum[N]; //前缀和 
 8 void init() { //初始化 
 9     mul[1] = 1;
10     sum[1] = 0;
11     for (int i = 2; i < N; i++) {
12         sum[i] = sum[i - 1] + i; //前缀和
13         mul[i] = (i * mul[i - 1]) % mod; //前缀积
14     }
15 }
16 ll inv(ll a, ll b) {
17     ll ans = 1;
18     while (b) {
19         if (b & 1) {
20             ans = (ans * a) % mod;
21         }
22         a = (a * a) % mod;
23         b >>= 1;
24     }
25     return ans;
26 }
27 int main() {
28     ios::sync_with_stdio(false);
29     cin.tie(0);
30     cout.tie(0);
31     init();
32     int t;
33     cin >> t;
34     while (t--) {
35         int x;
36         cin >> x;
37         if (x == 1) {
38             cout << 1 << endl;
39             continue;
40         }
41         int l = 1, r = N + 1; 
42         while (l < r) {
43             int mid = (l + r + 1) / 2;
44             if (sum[mid] <= x) {
45                 l = mid;
46             } else {
47                 r = mid - 1;
48             }
49         }
50         //cout << l << endl;
51         int p = l;
52         int num = x - sum[p]; //num就是相差的值 
53         ll ans = 0;
54         if (num == l) { //如果num刚好和k相等 
55             // 2 3 4 5 6 7 7
56             // 3 4 5 6 7 9
57             ans = (mul[p] * inv(2, mod - 2) % mod * (p + 2)) % mod;
58         } else {
59             ans = (mul[p + 1] * inv(mul[p + 1 - num], mod - 2) % mod * mul[p - num]) % mod;
60         }
61         cout << ans << endl;
62     }
63     return 0;
64 }
原文地址:https://www.cnblogs.com/fx1998/p/13661868.html