题目
分析
记 F k ( n ) = f ( k , n ) F_k(n) = f(k, n) Fk(n)=f(k,n),统计每个 x k x^k xk 的贡献可以得到 F k ( n ) = ∑ i = 0 n − 1 ( 2 n − i − 1 ⋅ i k ) + n k F_k(n) = \sum_{i = 0}^{n - 1} \left(2^{n - i - 1} \cdot i^k\right) + n^k Fk(n)=i=0∑n−1(2n−i−1⋅ik)+nk 具体来说可以画个二叉树理解:树上深度为 i i i 的结点的权值为 ( n − i + 1 ) k (n - i + 1)^k (n−i+1)k,根以及他的右子树权值和为 F k ( n ) F_k(n) Fk(n),根的左儿子和根的左儿子的右子树权值和 F k ( n − 1 ) F_k(n - 1) Fk(n−1),以此类推。
显然不能直接插,因为
n
n
n 在指数上。化简一下:
F
k
(
n
)
=
∑
i
=
0
n
−
1
(
2
n
−
i
−
1
⋅
i
k
)
+
n
k
=
2
n
−
1
∑
i
=
0
n
−
1
i
k
2
i
+
n
k
\begin{aligned} F_k(n) &= \sum_{i = 0}^{n - 1} \left(2^{n - i - 1} \cdot i^k\right) + n^k \\ &= 2^{n - 1}\sum_{i = 0}^{n - 1} \frac{i^k}{2^i} + n^k \end{aligned}
Fk(n)=i=0∑n−1(2n−i−1⋅ik)+nk=2n−1i=0∑n−12iik+nk 令
a
=
1
2
a = \frac{1}{2}
a=21,则
F
k
(
n
)
=
2
n
−
1
∑
i
=
0
n
−
1
a
i
i
k
+
n
k
F_k(n) = 2^{n - 1}\sum_{i = 0}^{n - 1} a^ii^k + n^k
Fk(n)=2n−1i=0∑n−1aiik+nk 指数转下降幂可以方便错位相减找递推式,进而找到指数函数的多项式形式:
F
k
(
n
)
=
2
n
−
1
∑
i
=
0
n
−
1
(
a
i
∑
j
=
0
k
{
k
j
}
i
j
‾
)
+
n
k
=
2
n
−
1
∑
j
=
0
k
{
k
j
}
∑
i
=
0
n
−
1
a
i
i
j
‾
+
n
k
\begin{aligned} F_k(n) &= 2^{n - 1}\sum_{i = 0}^{n - 1}\left(a^i \sum_{j = 0}^k {k \brace j} i^{\underline j}\right) + n^k \\ &= 2^{n - 1} \sum_{j = 0}^k {k \brace j} \sum_{i = 0}^{n - 1} a^ii^{\underline j} + n^k \end{aligned}
Fk(n)=2n−1i=0∑n−1(aij=0∑k{jk}ij)+nk=2n−1j=0∑k{jk}i=0∑n−1aiij+nk 令
S
k
(
n
)
=
∑
i
=
0
n
−
1
a
i
i
k
‾
S_k(n) = \sum_{i = 0}^{n - 1} a^ii^{\underline k}
Sk(n)=∑i=0n−1aiik,则
F
k
(
n
)
=
2
n
−
1
∑
j
=
0
k
{
k
j
}
S
j
(
n
)
+
n
k
F_k(n) = 2^{n - 1} \sum_{j = 0}^k {k \brace j} S_j(n) + n^k
Fk(n)=2n−1j=0∑k{jk}Sj(n)+nk
指数转下降幂:
{ n m } {n \brace m} {mn} 表示第二类斯特林数,即“ n n n 个不同的球,放入 m m m 个相同的盒子,盒子不可以为空的方案数”。有公式 n k = ∑ i = 0 k { k i } ⋅ i ! ⋅ C n i n^k = \sum_{i = 0}^{k} {k \brace i} \cdot i! \cdot C_n^i nk=i=0∑k{ik}⋅i!⋅Cni 等式左边是“ k k k 个不同的球放入 n n n 个不同的盒子,盒子可以为空的方案数”,右边即为枚举不为空的盒子数,分别计算,因此两边相等。
把组合数拆开可以得到: n k = ∑ i = 0 k { k i } ⋅ n i ‾ n^k = \sum_{i = 0}^{k} {k \brace i} \cdot n^{\underline i} nk=i=0∑k{ik}⋅ni
考虑求
S
k
(
n
)
S_k(n)
Sk(n) 的递推式,用错位相减法:
S
k
(
n
)
=
∑
i
=
0
n
−
1
a
i
i
k
‾
a
S
k
(
n
)
=
∑
i
=
1
n
a
i
(
i
−
1
)
k
‾
⇒
(
1
−
a
)
S
k
(
n
)
=
∑
i
=
1
n
−
1
a
i
[
i
k
‾
−
(
i
−
1
)
k
‾
]
+
a
0
0
k
‾
−
a
n
(
n
−
1
)
k
‾
=
∑
i
=
1
n
a
i
[
i
k
‾
−
(
i
−
1
)
k
‾
]
−
a
n
n
k
‾
+
a
n
(
n
−
1
)
k
+
a
0
0
k
‾
−
a
n
(
n
−
1
)
k
=
∑
i
=
1
n
a
i
[
i
k
‾
−
(
i
−
1
)
k
‾
]
−
a
n
n
k
‾
+
a
0
0
k
‾
=
∑
i
=
1
n
a
i
(
i
−
1
)
k
−
1
‾
[
i
−
(
i
−
k
)
]
−
a
n
n
k
‾
+
a
0
0
k
‾
=
a
k
∑
i
=
0
n
−
1
a
i
i
k
−
1
‾
−
a
n
n
k
‾
+
a
0
0
k
‾
=
a
k
S
k
−
1
(
n
)
−
a
n
n
k
‾
+
a
0
0
k
‾
⇒
S
k
(
n
)
=
a
k
1
−
a
S
k
−
1
(
n
)
−
a
n
n
k
‾
+
a
0
0
k
‾
1
−
a
\begin{aligned} S_k(n) &= \sum_{i = 0}^{n - 1} a^ii^{\underline k} \\ aS_k(n) &= \sum_{i = 1}^{n} a^i(i - 1)^{\underline k} \\ \Rightarrow (1 - a)S_k(n) &= \sum_{i = 1}^{n - 1} a^i \left[i^{\underline k} - (i - 1)^{\underline k}\right] + a^00^{\underline k} - a^n(n - 1)^{\underline k} \\ &= \sum_{i = 1}^n a^i \left[i^{\underline k} - (i - 1)^{\underline k}\right] - a^nn^{\underline k} + a^n(n - 1)^k + a^00^{\underline k} - a^n(n - 1)^k \\ &= \sum_{i = 1}^n a^i \left[i^{\underline k} - (i - 1)^{\underline k}\right] - a^nn^{\underline k} + a^00^{\underline k} \\ &= \sum_{i = 1}^n a^i (i - 1)^{\underline{k - 1}}[i - (i - k)] - a^nn^{\underline k} + a^00^{\underline k} \\ &= ak\sum_{i = 0}^{n - 1} a^i i^{\underline{k - 1}} - a^nn^{\underline k} + a^00^{\underline k} \\ &= akS_{k - 1}(n) - a^nn^{\underline k} + a^00^{\underline k} \\ \Rightarrow S_k(n) &= \frac{ak}{1 - a} S_{k - 1}(n) - \frac{a^nn^{\underline k} + a^00^{\underline k}}{1 - a} \end{aligned}
Sk(n)aSk(n)⇒(1−a)Sk(n)⇒Sk(n)=i=0∑n−1aiik=i=1∑nai(i−1)k=i=1∑n−1ai[ik−(i−1)k]+a00k−an(n−1)k=i=1∑nai[ik−(i−1)k]−annk+an(n−1)k+a00k−an(n−1)k=i=1∑nai[ik−(i−1)k]−annk+a00k=i=1∑nai(i−1)k−1[i−(i−k)]−annk+a00k=aki=0∑n−1aiik−1−annk+a00k=akSk−1(n)−annk+a00k=1−aakSk−1(n)−1−aannk+a00k 特别地,
S
0
(
n
)
=
∑
i
=
0
n
−
1
a
i
=
1
−
a
n
1
−
a
S_0(n) = \sum_{i = 0}^{n - 1} a^i = \frac{1 - a^n}{1 - a}
S0(n)=∑i=0n−1ai=1−a1−an。将
a
a
a 替换为
1
2
\frac{1}{2}
21 得到
S
k
(
n
)
=
{
2
(
1
−
1
2
n
)
k
=
1
k
S
k
−
1
(
n
)
−
n
k
‾
2
n
−
1
k
>
1
S_k(n) = \begin{cases} 2\left(1 - \dfrac{1}{2^n}\right) & k = 1 \\ k S_{k - 1}(n) - \dfrac{n^{\underline k}}{2^{n - 1}} & k > 1 \end{cases}
Sk(n)=⎩⎪⎨⎪⎧2(1−2n1)kSk−1(n)−2n−1nkk=1k>1 这时候手刨几项:
- S 0 ( n ) = 2 ( 1 − 1 2 n ) S_0(n) = 2(1 - \frac{1}{2^n}) S0(n)=2(1−2n1)
- S 1 ( n ) = 1 ⋅ 2 ( 1 − 1 2 n ) − n 2 n − 1 S_1(n) = 1 \cdot 2(1 - \frac{1}{2^n}) - \frac{n}{2^{n - 1}} S1(n)=1⋅2(1−2n1)−2n−1n
- S 2 ( n ) = 2 [ 1 ⋅ 2 ( 1 − 1 2 n ) − n 2 n − 1 ] − n ( n − 1 ) 2 n S_2(n) = 2\left[1 \cdot 2(1 - \frac{1}{2^n}) - \frac{n}{2^{n - 1}}\right] - \frac{n(n - 1)}{2^n} S2(n)=2[1⋅2(1−2n1)−2n−1n]−2nn(n−1)
- S 3 ( n ) = 3 { 2 [ 1 ⋅ 2 ( 1 − 1 2 n ) − n 2 n − 1 ] − n ( n − 1 ) 2 n } − n ( n − 1 ) ( n − 2 ) 2 n S_3(n) = 3 \left\{2\left[1 \cdot 2(1 - \frac{1}{2^n}) - \frac{n}{2^{n - 1}}\right] - \frac{n(n - 1)}{2^n}\right\} - \frac{n(n - 1)(n - 2)}{2^n} S3(n)=3{2[1⋅2(1−2n1)−2n−1n]−2nn(n−1)}−2nn(n−1)(n−2)
接下来就是神仙操作了,还记得常系数齐次线性递推么? 将常数项分成两部分,将含
n
n
n 的部分提出一个
1
2
n
\frac{1}{2^n}
2n1:
S
3
(
n
)
=
3
{
2
[
1
⋅
2
(
1
−
1
2
n
)
−
n
2
n
−
1
]
−
n
(
n
−
1
)
2
n
}
−
n
(
n
−
1
)
(
n
−
2
)
2
n
=
12
−
1
2
n
[
12
+
6
n
+
3
n
(
n
−
1
)
+
n
(
n
−
1
)
(
n
−
2
)
]
\begin{aligned} S_3(n) &= 3 \left\{2\left[1 \cdot 2(1 - \frac{1}{2^n}) - \frac{n}{2^{n - 1}}\right] - \frac{n(n - 1)}{2^n}\right\} - \frac{n(n - 1)(n - 2)}{2^n} \\ &= 12 - \frac{1}{2^n}[12 + 6n + 3n(n - 1) + n(n - 1)(n- 2)] \end{aligned}
S3(n)=3{2[1⋅2(1−2n1)−2n−1n]−2nn(n−1)}−2nn(n−1)(n−2)=12−2n1[12+6n+3n(n−1)+n(n−1)(n−2)] 两个
12
12
12 是一样的!其实原因就在于
S
0
(
n
)
=
2
(
1
−
1
2
n
)
S_0(n) = 2(1 - \frac{1}{2^n})
S0(n)=2(1−2n1),两个
1
1
1 可以分给两边,使得新的一个
S
k
(
n
)
S_k(n)
Sk(n) 可以写成
S
k
(
n
)
=
G
k
(
0
)
−
G
k
(
n
)
2
n
S_k(n) = G_k(0) - \frac{G_k(n)}{2^n}
Sk(n)=Gk(0)−2nGk(n) 其中
G
k
(
n
)
G_k(n)
Gk(n) 显然是一个
k
k
k 次多项式,而
G
k
(
0
)
G_k(0)
Gk(0) 正式它的常数项!
可能的疑问是,为什么不能直接提出一个 1 2 n \frac{1}{2^n} 2n1,变成 S k ( n ) = T k ( n ) 2 n S_k(n) = \frac{T_k(n)}{2^n} Sk(n)=2nTk(n) 原因是, S 0 ( n ) S_0(n) S0(n) 事实上是两部分,如果不分开的话, T k ( n ) T_k(n) Tk(n) 中会有 2 n 2^n 2n 这样的东西( S 0 ( n ) S_0(n) S0(n) 中的 “ 1 1 1”造成的),所以不可以直接提 1 2 n \frac{1}{2^n} 2n1。分开过后, G k ( n ) G_k(n) Gk(n) 就不含指数函数了!
回代进 F k ( n ) F_k(n) Fk(n): F k ( n ) = 2 n − 1 ∑ j = 0 k { k j } S j ( n ) + n k = 2 n − 1 ∑ j = 0 k { k j } ( G j ( 0 ) − G j ( n ) 2 n ) + n k = 2 n − 1 ( ∑ i = 0 k { k i } G i ( 0 ) − ∑ i = 0 k { k i } G i ( n ) 2 n ) + n k \begin{aligned} F_k(n) &= 2^{n - 1} \sum_{j = 0}^k {k \brace j} S_j(n) + n^k \\ &= 2^{n - 1} \sum_{j = 0}^k {k \brace j} \left(G_j(0) - \frac{G_j(n)}{2^n}\right) + n^k \\ &= 2^{n - 1} \left(\sum_{i = 0}^k {k \brace i} G_i(0) - \frac{\sum_{i = 0}^k {k \brace i} G_i(n)}{2^n}\right) + n^k \end{aligned} Fk(n)=2n−1j=0∑k{jk}Sj(n)+nk=2n−1j=0∑k{jk}(Gj(0)−2nGj(n))+nk=2n−1(i=0∑k{ik}Gi(0)−2n∑i=0k{ik}Gi(n))+nk 令 H k ( n ) = ∑ i = 0 k { k i } G i ( n ) H_k(n) = \sum_{i = 0}^k {k \brace i} G_i(n) Hk(n)=i=0∑k{ik}Gi(n) 显然 H i ( n ) H_i(n) Hi(n) 为 k k k 次多项式,且 F k ( n ) = 2 n − 1 ( H k ( 0 ) − H k ( n ) 2 n ) + n k F_k(n) = 2^{n - 1}\left(H_k(0) - \frac{H_k(n)}{2^n}\right) + n^k Fk(n)=2n−1(Hk(0)−2nHk(n))+nk 接下来求出 R k ( n ) = H k ( 0 ) − 1 2 n H k ( n ) R_k(n) = H_k(0) - \frac{1}{2^n}H_k(n) Rk(n)=Hk(0)−2n1Hk(n) 即可。
-
H k ( 0 ) H_k(0) Hk(0) 的部分:
这个函数我们一项都算不出来,回顾一下开头,发现 R k ( n ) R_k(n) Rk(n) 可以算: R k ( n ) = ∑ i = 0 n − 1 i k 2 i R_k(n) = \sum_{i = 0}^{n - 1} \frac{i^k}{2^i} Rk(n)=i=0∑n−12iik 把式子弄一下 H k ( n ) = 2 n H k ( 0 ) − 2 n R k ( n ) H_k(n) = 2^nH_k(0) - 2^nR_k(n) Hk(n)=2nHk(0)−2nRk(n) 那么用一个二元组 { x , y } \{x, y\} {x,y} 表示 H k ( n ) H_k(n) Hk(n) 即 H k ( n ) = x H k ( 0 ) − y H_k(n) = xH_k(0) - y Hk(n)=xHk(0)−y,这个二元组显然可以快速地进行加、减和乘一个常的运算。有了这些我们就可以用 H k ( 0 ) , H k ( 1 ) , ⋯ , H k ( k ) H_k(0), H_k(1), \cdots, H_k(k) Hk(0),Hk(1),⋯,Hk(k) 的二元表示插出 H k ( k + 1 ) H_k(k + 1) Hk(k+1) 的二元表示记为 { a 1 , b 1 } \{a_1,b_1\} {a1,b1}。 H k ( n ) = 2 n H k ( 0 ) − 2 n R k ( n ) H_k(n) = 2^nH_k(0) - 2^nR_k(n) Hk(n)=2nHk(0)−2nRk(n) 也能得到一个 H k ( k + 1 ) H_k(k + 1) Hk(k+1) 的二元表示记为 { a 2 , b 2 } \{a_2, b_2\} {a2,b2}。由 H k ( k + 1 ) = H k ( k + 1 ) H_k(k + 1) = H_k(k + 1) Hk(k+1)=Hk(k+1) 得到 a 1 H k ( 0 ) − b 1 = a 2 H k ( 0 ) − b 2 a_1H_k(0) - b_1 = a_2H_k(0) - b_2 a1Hk(0)−b1=a2Hk(0)−b2 于是 H k ( 0 ) = b 1 − b 2 a 1 − a 2 H_k(0) = \frac{b_1 - b_2}{a_1 - a_2} Hk(0)=a1−a2b1−b2注意这两个二元表示是不等价的!可以理解为只要给出次数,拉格朗日插值就可以形式化地创造一个表示方法,这个新的值的计算方式与你原来计算点值的方式没有任何关系,因此这个方程有解。
-
H k ( n ) H_k(n) Hk(n) 的部分:
得到 H k ( 0 ) H_k(0) Hk(0),就知道了 H k ( 1 ) , H k ( 2 ) , ⋯ , H k ( k ) H_k(1), H_k(2), \cdots, H_k(k) Hk(1),Hk(2),⋯,Hk(k),直接拉格朗日插值即可。
还有一个细节是算 2 n 2^n 2n 什么的, n n n 有一百万位显然不能快速幂……要用欧拉定理: a φ ( p ) ≡ 1 ( mod p ) a^{\varphi(p)} \equiv 1 \ (\text{mod} \ p) aφ(p)≡1 (mod p) 这里 p = 1 0 9 + 7 p = 10^9 + 7 p=109+7 是个质数,所以 φ ( p ) = p − 1 \varphi(p) = p - 1 φ(p)=p−1,所以 2 n ≡ 2 n mod ( p − 1 ) ( mod p ) 2^n \equiv 2^{n \ \text{mod} \ (p - 1)} \ (\text{mod} \ p) 2n≡2n mod (p−1) (mod p)。
做完了。这题太夸张了。据说 高阶差分 可以简单一点点,或者最开始就往 常系数线性递推 化。太菜了看不怎么懂……
代码
变量名有出入,但思路是完全一致的。
#include <algorithm>
#include <cstdio>
#include <cstring>
typedef std::pair<int, int> PII;
const int MAXN = 1000000;
const int MOD = 1000000007;
const int PHI = MOD - 1;
inline int Add(int x, const int &y) {
x += y; if (x >= MOD) x -= MOD; return x;
}
inline int Sub(int x, const int &y) {
x -= y; if (x < 0) x += MOD; return x;
}
inline int Mul(const int &x, const int &y) {
return (long long)x * y % MOD;
}
int Pow(int x, int y) {
int ret = 1;
while (y) {
if (y & 1)
ret = Mul(ret, x);
y >>= 1;
x = Mul(x, x);
}
return ret;
}
const int INV2 = Pow(2, MOD - 2);
PII operator + (const PII &x, const PII &y) {
return std::make_pair(Add(x.first, y.first), Add(x.second, y.second));
}
PII operator - (const PII &x, const PII &y) {
return std::make_pair(Sub(x.first, y.first), Sub(x.second, y.second));
}
PII operator * (const PII &x, const int &y) {
return std::make_pair(Mul(x.first, y), Mul(x.second, y));
}
int N, P, K;
int Fac[MAXN + 5], InvFac[MAXN + 5];
int H[MAXN + 5];
int F[MAXN + 5];
PII G[MAXN + 5];
int Pre[MAXN + 5], Suf[MAXN + 5];
void Init(int n) {
Pre[0] = n;
for (int i = 1; i <= K; i++)
Pre[i] = Mul(Pre[i - 1], Sub(n, i));
Suf[K + 1] = 1;
for (int i = K; i >= 0; i--)
Suf[i] = Mul(Suf[i + 1], Sub(n, i));
}
PII Lagrange1(int n) {
Init(n);
PII res(0, 0);
for (int i = 0; i <= K; i++) {
int A = Mul(i ? Pre[i - 1] : 1, Suf[i + 1]);
int B = Mul(InvFac[i], InvFac[K - i]);
PII C = G[i] * Mul(A, B);
res = ((K - i) & 1) ? (res - C) : (res + C);
// printf("%d %d (%d, %d)\n", A, B, res.first, res.second);
}
return res;
}
int Lagrange2(int n) {
Init(n);
int res = 0;
for (int i = 0; i <= K; i++) {
int A = Mul(i ? Pre[i - 1] : 1, Suf[i + 1]);
int B = Mul(InvFac[i], InvFac[K - i]);
int C = Mul(H[i], Mul(A, B));
res = ((K - i) & 1) ? Sub(res, C) : Add(res, C);
}
return res;
}
int main() {
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9') {
P = ((long long)P * 10 + c - '0') % PHI;
N = ((long long)N * 10 + c - '0') % MOD;
c = getchar();
}
scanf("%d", &K);
Fac[0] = 1;
for (int i = 1; i <= K; i++)
Fac[i] = Mul(Fac[i - 1], i);
InvFac[K] = Pow(Fac[K], MOD - 2);
for (int i = K - 1; i >= 0; i--)
InvFac[i] = Mul(InvFac[i + 1], i + 1);
for (int i = 1; i <= K + 1; i++)
F[i] = Add(F[i - 1], Mul(Pow(INV2, i - 1), Pow(i - 1, K)));
for (int i = 0; i <= K + 1; i++)
G[i] = std::make_pair(Pow(2, i), Mul(Pow(2, i), F[i]));
PII x = G[K + 1], y = Lagrange1(K + 1);
int A = Sub(y.second, x.second);
int B = Sub(x.first, y.first);
H[0] = Mul(A, Pow(B, MOD - 2));
for (int i = 1; i <= K; i++)
H[i] = Add(Mul(G[i].first, H[0]), G[i].second);
int Ans = Sub(Mul(Lagrange2(N), Pow(INV2, P)), H[0]);
Ans = Add(Mul(Pow(2, P ? (P - 1) : (MOD - 2)), Ans), Pow(N, K));
printf("%d", Ans);
return 0;
}