-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy path1029_Array Cutting Score (35).cpp
88 lines (77 loc) · 2.55 KB
/
1029_Array Cutting Score (35).cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <vector>
using namespace std;
/*
Solution 1:
dp[i,j] i个选j组最后得到的结果
dp[i,j] = products of belows
dp[i-1, j-1]*(dp[i, 1] - dp[i-1, 1])^(C[i-2, j-2])
dp[i-2, j-1]*(dp[i, 1] - dp[i-2, 1])^(C[i-3, j-2])
......
dp[j-1, j-1]*(dp[i, 1] - dp[j-1, 1])^(C[j-2, j-2])
递推O(n), 二维O(n^2), 复杂度O(n^3)
Soution 2:
......[X]...... 计算当前X的组对于最后分成m组后乘积的贡献次数,
如果x是sum(i,...,j), 则计算次数y
1. m == 1 && i == 1 && j == n => y = 1
2. i == 1 && m-2 >= 0 && n-j-1 >= m-2 => y = c[n-j-1, m-2]
3. j == n && m-2 >= 0 && i-2 >= m-2 => y = c[i-2, m-2]
4. i != 1 && j != n && m-3 >= 0 && i-2+n-j-1 >= m-3 => y = c[i-2+n-j-1, m-3] i-2+n-j-1表示X两边可以分组的位置,如果他们分成m-1组(X占了一组), 则需要在这些可能位置插入m-3个隔板。
Extra:
(a+b) % p = (a%p + b%p) % p
a^b % p = (a%p)^b % p
if p is prime, a^b % p = a^(b % phi(p) + phi(p)) % p = a^(b % (p-1)) % p
*/
typedef unsigned long long int64;
const int64 maxn(1005), mod(1000000007);
int64 c[maxn][maxn];
vector<int64> a, sum;
//快速幂 a^n % p
int64 pow(int64 a, int64 n, int64 p) {
int64 ans = 1;
while(n > 0)
{
if(n & 1) ans = ans * a % p;
a = a * a % p;
n >>= 1;
}
return ans;
}
//计算C(m, n)
void calcC(int m, int n, int64 p) {
for (int i = 0; i <= m; i++)
for (int j = 0; j <= min(i, n); j++) {
if (j == 0|| i == j) c[i][j] = 1;
else c[i][j] = ((c[i-1][j-1] % p) + (c[i-1][j] % p)) % p;
}
}
int main() {
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
a.resize(n+1);
sum.resize(n+1);
a[0] = sum[0] = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum[i] = (sum[i-1] + a[i]) % mod;
}
calcC(n, m, mod-1);
int64 result = 1;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) {
int64 x = (sum[j] - sum[i-1] + mod) % mod;
int64 y = 0;
// cout << "1: " << i << " " << j << " " << m-2 << endl;
// cout << "2: " << n-j << " " << i-1 << endl;
if (m == 1 && i == 1 && j == n) y = 1;
else if (i == 1 && m-2 >= 0 && n-j-1 >= m-2) y = c[n-j-1][m-2];
else if (j == n && m-2 >= 0 && i-2 >= m-2) y = c[i-2][m-2];
else if (i != 1 && j != n && m-3 >= 0 && i-2+n-j-1 >= m-3) y = c[i-2+n-j-1][m-3];
// cout << "3: " << x << " " << y << endl << endl;
result *= pow(x, y, mod);
result %= mod;
}
cout << result << endl;
return 0;
}