Statement
Solution
经过推导发现答案为:
∑
i
=
1
m
+
1
[
∑
j
=
1
n
−
a
i
−
1
j
m
+
1
−
∑
j
=
i
m
(
a
j
−
a
i
−
1
)
m
+
1
]
\sum_{i=1}^{m+1}\left[\sum_{j=1}^{n-a_{i-1}}j^{m+1}-\sum_{j=i}^m(a_j-a_{i-1})^{m+1}\right]
i=1∑m+1[j=1∑n−ai−1jm+1−j=i∑m(aj−ai−1)m+1]
复杂度瓶颈在
∑
i
=
1
n
i
k
\sum_{i=1}^ni^k
∑i=1nik
对以上和式用扰动法
记 S ( k , n ) = ∑ i = 1 n i k S(k,n)=\sum_{i=1}^ni^k S(k,n)=∑i=1nik
S
(
k
+
1
,
n
)
=
∑
i
=
1
n
i
k
+
1
S(k+1,n)=\sum_{i=1}^ni^{k+1}
S(k+1,n)=i=1∑nik+1
S
(
k
+
1
,
n
)
+
(
n
+
1
)
k
+
1
=
∑
i
=
1
n
(
i
+
1
)
k
+
1
+
1
S(k+1,n)+(n+1)^{k+1}=\sum_{i=1}^{n}(i+1)^{k+1}+1
S(k+1,n)+(n+1)k+1=i=1∑n(i+1)k+1+1
S
(
k
+
1
,
n
)
+
(
n
+
1
)
k
+
1
=
∑
i
=
1
n
∑
j
=
0
k
+
1
(
k
+
1
j
)
i
j
+
1
S(k+1,n)+(n+1)^{k+1}=\sum_{i=1}^n\sum_{j=0}^{k+1}\dbinom{k+1}{j}i^j+1
S(k+1,n)+(n+1)k+1=i=1∑nj=0∑k+1(jk+1)ij+1
S
(
k
+
1
,
n
)
+
(
n
+
1
)
k
+
1
=
∑
i
=
0
k
+
1
(
k
+
1
i
)
S
(
i
,
n
)
+
1
S(k+1,n)+(n+1)^{k+1}=\sum_{i=0}^{k+1}\dbinom{k+1}{i}S(i,n)+1
S(k+1,n)+(n+1)k+1=i=0∑k+1(ik+1)S(i,n)+1
S
(
k
+
1
,
n
)
+
(
n
+
1
)
k
+
1
=
S
(
k
+
1
,
n
)
+
1
+
(
k
+
1
k
)
S
(
k
,
n
)
+
∑
i
=
0
k
−
1
(
k
+
1
i
)
S
(
i
,
n
)
S(k+1,n)+(n+1)^{k+1}=S(k+1,n)+1+\dbinom{k+1}{k}S(k,n)+\sum_{i=0}^{k-1}\dbinom{k+1}{i}S(i,n)
S(k+1,n)+(n+1)k+1=S(k+1,n)+1+(kk+1)S(k,n)+i=0∑k−1(ik+1)S(i,n)
S
(
k
,
n
)
=
(
n
+
1
)
k
+
1
−
1
−
∑
i
=
0
k
−
1
(
k
+
1
i
)
S
(
i
,
n
)
(
k
+
1
k
)
S(k,n)=\dfrac{(n+1)^{k+1}-1-\sum\limits_{i=0}^{k-1}\dbinom{k+1}{i}S(i,n)}{\dbinom{k+1}{k}}
S(k,n)=(kk+1)(n+1)k+1−1−i=0∑k−1(ik+1)S(i,n)
发现其为一个
k
+
1
k+1
k+1次多项式,拉格朗日插值即可,时间复杂度为
O
(
T
m
3
)
\mathcal {O}(Tm^3)
O(Tm3)。
f ( x ) = ∑ i = 1 m + 3 y i ∏ j ≠ i x − x j x i − x j f(x)=\sum_{i=1}^{m+3}y_i\prod_{j\not ={i}}\dfrac{x-x_j}{x_i-x_j} f(x)=i=1∑m+3yij=i∏xi−xjx−xj
Code
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 55;
const int P = 1E9 + 7;
int A[MAXN];
inline int qPow(int a, int b) {
int res = 1;
for (; b; b >>= 1, a = 1ll * a * a % P)
(b & 1) && (res = 1ll * res * a % P);
return res;
}
inline int calc(long long n, int k) {
if (n <= k + 2)
return A[n];
int res = 0;
for (int i = 1;i <= k + 2; ++i) {
int u = 1, v = 1;
for (int j = 1;j <= k + 2; ++j)
if (i != j)
u = 1ll * u * ((n - j) % P + P) % P,
v = 1ll * v * (i - j + P) % P;
u = 1ll * u * qPow(v, P - 2) % P * A[i] % P,
res = (res + u) % P;
}
return res;
}
int main(void) {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int testCase = 0;
cin >> testCase;
while (testCase--) {
long long n;
int m = 0, ans = 0;
cin >> n >> m;
vector <long long> v(m);
for (long long& a : v)
cin >> a;
sort(v.begin(), v.end());
for (int i = 1;i <= m + 3; ++i)
A[i] = (A[i - 1] + qPow(i, m + 1)) % P;
for (int i = 0, o = 0;i <= m; ++i) {
ans = (ans + calc(n - (i ? v[i - 1] : 0), m + 1)) % P, o = 0;
for (int j = i;j < m; ++j)
o = (o + qPow(v[j] - (i ? v[i - 1] : 0), m + 1)) % P;
ans = (ans - o + P) % P;
}
cout << ans << '\n';
}
return 0;
}