勘破神机
题目链接:luogu P5320
题目大意
给你
l
,
r
,
k
l,r,k
l,r,k(其中
l
,
r
l,r
l,r 很大,
k
≤
501
k\leq 501
k≤501),求:
1
r
−
l
+
1
∑
i
=
l
r
C
f
i
k
\dfrac{1}{r-l+1}\sum\limits_{i=l}^rC_{f_i}^k
r−l+11i=l∑rCfik
1
r
−
l
+
1
∑
i
=
l
r
C
g
i
k
\dfrac{1}{r-l+1}\sum\limits_{i=l}^rC_{g_i}^k
r−l+11i=l∑rCgik
f
n
f_n
fn 为一个
2
∗
n
2*n
2∗n 的网格往里面放
1
∗
2
1*2
1∗2 的块填满的方案,
g
n
g_n
gn 则是一个
3
∗
n
3*n
3∗n 的网格。
思路
首先
2
2
2 的答案我们可以看出答案其实是贴合与斐波那契数列
F
i
F_i
Fi。
具体看一看会发现是
f
i
=
F
i
+
1
f_i=F_{i+1}
fi=Fi+1,所以记得
l
,
r
l,r
l,r 加一。
然后斐波那契嘛,
f
i
=
f
i
−
1
+
f
i
−
2
f_i=f_{i-1}+f_{i-2}
fi=fi−1+fi−2,然后可以表示成那个带根号的通式嘛。
然后我们通过特征方程这个东西,我们知道如果有一个二阶递推式,我们可以把它表示成一个通项公式。
于是开始了下面的步骤:
2
f
i
=
f
i
−
1
+
f
i
−
2
f_i=f_{i-1}+f_{i-2}
fi=fi−1+fi−2
f
[
n
]
=
5
5
[
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
]
f[n]=\dfrac{\sqrt{5}}{5}[(\dfrac{1+\sqrt{5}}{2})^n-(\dfrac{1-\sqrt{5}}{2})^n]
f[n]=55[(21+5)n−(21−5)n]
A
=
5
5
,
α
=
1
+
5
2
,
B
=
−
5
5
,
β
=
1
−
5
2
A=\dfrac{\sqrt{5}}{5},\alpha=\dfrac{1+\sqrt{5}}{2},B=-\dfrac{\sqrt{5}}{5},\beta=\dfrac{1-\sqrt{5}}{2}
A=55,α=21+5,B=−55,β=21−5
3
思考要如何推出 f f f 的值,首先把 f 0 , f 1 f_0,f_1 f0,f1 求出,因为可以作为边界,而且也是特征方程需要的。
f
0
=
1
,
f
1
=
3
f_0=1,f_1=3
f0=1,f1=3
f
i
f_i
fi 长度为
2
i
2i
2i 的答案(所以记得两个边界要改,但是注意
r
−
l
+
1
r-l+1
r−l+1 要用之前的值)
于是进行思考,发现可以新放进来一个
2
∗
3
2*3
2∗3 的,然后有
3
3
3 中方法。
然后发现只有这样不够,因为可能会出现这样的:
而且呢,中间的粉色可能不止两个:
然后粉色可以是在
1
,
2
1,2
1,2 行或者
2
,
3
2,3
2,3 行,所以我们可以列出这样的式子:
f
i
=
3
f
i
−
1
+
2
(
f
i
−
2
+
f
i
−
3
+
.
.
.
)
f_{i}=3f_{i-1}+2(f_{i-2}+f_{i-3}+...)
fi=3fi−1+2(fi−2+fi−3+...)
f
i
=
3
f
i
−
1
+
2
(
∑
j
=
0
i
−
2
f
j
)
f_i=3f_{i-1}+2(\sum\limits_{j=0}^{i-2}f_j)
fi=3fi−1+2(j=0∑i−2fj)
f
i
−
1
=
3
f
i
−
2
+
2
(
∑
j
=
0
i
−
3
f
j
)
f_{i-1}=3f_{i-2}+2(\sum\limits_{j=0}^{i-3}f_j)
fi−1=3fi−2+2(j=0∑i−3fj)
f
i
−
f
i
−
1
=
3
f
i
−
1
−
f
i
−
2
f_i-f_{i-1}=3f_{i-1}-f_{i-2}
fi−fi−1=3fi−1−fi−2
f
i
=
4
f
i
−
1
−
f
i
−
2
f_i=4f_{i-1}-f_{i-2}
fi=4fi−1−fi−2
搞出了二阶递推式,就直接开始求通项公式吧!
f
i
−
4
f
i
−
1
+
f
i
−
2
=
0
f_i-4f_{i-1}+f_{i-2}=0
fi−4fi−1+fi−2=0
x
2
−
4
x
+
1
=
0
x^2-4x+1=0
x2−4x+1=0
x
1
=
4
+
2
3
2
,
x
2
=
4
−
2
3
2
x_1=\dfrac{4+2\sqrt{3}}{2},x_2=\dfrac{4-2\sqrt{3}}{2}
x1=24+23,x2=24−23
x
1
=
2
+
3
,
x
2
=
2
−
3
x_1=2+\sqrt{3},x_2=2-\sqrt{3}
x1=2+3,x2=2−3
带入
f
0
=
1
,
f
1
=
3
f_0=1,f_1=3
f0=1,f1=3
A
x
1
n
+
B
x
2
n
=
f
n
Ax_1^n+Bx_2^n=f_n
Ax1n+Bx2n=fn
A
+
B
=
1
A+B=1
A+B=1
A
(
2
+
3
)
+
B
(
2
−
3
)
=
3
A(2+\sqrt{3})+B(2-\sqrt{3})=3
A(2+3)+B(2−3)=3
A
(
2
+
3
)
+
(
1
−
A
)
(
2
−
3
)
=
3
A(2+\sqrt3)+(1-A)(2-\sqrt3)=3
A(2+3)+(1−A)(2−3)=3
A
(
2
+
3
)
+
2
−
3
−
A
(
2
−
3
)
=
3
A(2+\sqrt3)+2-\sqrt{3}-A(2-\sqrt3)=3
A(2+3)+2−3−A(2−3)=3
2
3
A
=
1
+
3
2\sqrt3A=1+\sqrt3
23A=1+3
A
=
1
+
3
2
3
=
3
+
3
6
A=\dfrac{1+\sqrt3}{2\sqrt3}=\dfrac{\sqrt3+3}{6}
A=231+3=63+3
A
=
3
+
3
6
,
B
=
3
−
3
6
A=\dfrac{3+\sqrt3}{6},B=\dfrac{3-\sqrt3}{6}
A=63+3,B=63−3
f
[
n
]
=
3
+
3
6
(
4
+
2
3
2
)
n
+
3
−
3
6
(
4
−
2
3
2
)
n
f[n]=\dfrac{3+\sqrt3}{6}(\dfrac{4+2\sqrt{3}}{2})^n+\dfrac{3-\sqrt3}{6}(\dfrac{4-2\sqrt{3}}{2})^n
f[n]=63+3(24+23)n+63−3(24−23)n
A
=
3
+
3
6
,
α
=
4
+
2
3
2
,
B
=
3
−
3
6
,
β
=
4
−
2
3
2
A=\dfrac{3+\sqrt3}{6},\alpha=\dfrac{4+2\sqrt{3}}{2},B=\dfrac{3-\sqrt3}{6},\beta=\dfrac{4-2\sqrt{3}}{2}
A=63+3,α=24+23,B=63−3,β=24−23
A
=
3
+
3
6
,
α
=
2
+
3
,
B
=
3
−
3
6
,
β
=
2
−
3
A=\dfrac{3+\sqrt3}{6},\alpha=2+\sqrt{3},B=\dfrac{3-\sqrt3}{6},\beta=2-\sqrt{3}
A=63+3,α=2+3,B=63−3,β=2−3
于是我们似乎把 f i f_i fi 表示成了一个很好的形式,考虑开搞。
f
i
=
A
α
i
+
B
β
i
f_i=A\alpha^i+B\beta^i
fi=Aαi+Bβi
∑
i
=
0
n
(
f
i
k
)
\sum\limits_{i=0}^n\binom{f_i}{k}
i=0∑n(kfi)
∑
i
=
0
n
f
i
!
k
!
(
f
i
−
k
)
!
\sum\limits_{i=0}^n\dfrac{f_i!}{k!(f_i-k)!}
i=0∑nk!(fi−k)!fi!
∑
i
=
0
n
f
i
k
‾
k
!
\sum\limits_{i=0}^n\dfrac{f_i^{\underline k}}{k!}
i=0∑nk!fik
1
k
!
∑
i
=
0
n
∑
j
=
1
k
(
−
1
)
k
−
j
s
(
k
,
j
)
f
i
j
\dfrac{1}{k!}\sum\limits_{i=0}^n\sum\limits_{j=1}^k(-1)^{k-j}s(k,j)f_i^j
k!1i=0∑nj=1∑k(−1)k−js(k,j)fij(斯特林数与下降幂的转化)
(补充:
x
k
‾
=
∑
j
=
1
k
s
(
k
,
j
)
x
j
x^{\overline k}=\sum\limits_{j=1}^ks(k,j)x^j
xk=j=1∑ks(k,j)xj)
1
k
!
∑
i
=
1
k
(
−
1
)
k
−
i
s
(
k
,
i
)
∑
j
=
0
n
f
j
i
\dfrac{1}{k!}\sum\limits_{i=1}^k(-1)^{k-i}s(k,i)\sum\limits_{j=0}^nf_j^i
k!1i=1∑k(−1)k−is(k,i)j=0∑nfji
设
g
n
,
j
=
∑
i
=
0
n
f
i
j
g_{n,j}=\sum\limits_{i=0}^nf_i^j
gn,j=i=0∑nfij
f
i
=
A
α
i
+
B
β
i
f_i=A\alpha^i+B\beta^i
fi=Aαi+Bβi
g
n
,
j
=
∑
i
=
0
n
(
A
α
i
+
B
β
i
)
j
g_{n,j}=\sum\limits_{i=0}^n(A\alpha^i+B\beta^i)^j
gn,j=i=0∑n(Aαi+Bβi)j
g
n
,
j
=
∑
k
=
0
j
(
j
k
)
∑
i
=
0
n
(
A
α
i
)
k
(
B
β
i
)
j
−
k
g_{n,j}=\sum\limits_{k=0}^j\binom{j}{k}\sum\limits_{i=0}^n(A\alpha^i)^k(B\beta^i)^{j-k}
gn,j=k=0∑j(kj)i=0∑n(Aαi)k(Bβi)j−k
g
n
,
j
=
∑
k
=
0
j
(
j
k
)
A
k
B
j
−
k
∑
i
=
0
n
α
i
k
β
i
(
j
−
k
)
g_{n,j}=\sum\limits_{k=0}^j\binom{j}{k}A^kB^{j-k}\sum\limits_{i=0}^n\alpha^{ik}\beta^{i(j-k)}
gn,j=k=0∑j(kj)AkBj−ki=0∑nαikβi(j−k)
g
n
,
j
=
∑
k
=
0
j
(
j
k
)
A
k
B
j
−
k
1
−
α
(
n
+
1
)
k
β
(
n
+
1
)
(
j
−
k
)
1
−
α
k
β
j
−
k
g_{n,j}=\sum\limits_{k=0}^j\binom{j}{k}A^kB^{j-k}\dfrac{1-\alpha^{(n+1)k}\beta^{(n+1)(j-k)}}{1-\alpha^k\beta^{j-k}}
gn,j=k=0∑j(kj)AkBj−k1−αkβj−k1−α(n+1)kβ(n+1)(j−k)(等比数列求和)
1
k
!
∑
i
=
1
k
(
−
1
)
k
−
i
s
(
k
,
i
)
∑
j
=
0
n
f
j
i
\dfrac{1}{k!}\sum\limits_{i=1}^k(-1)^{k-i}s(k,i)\sum\limits_{j=0}^nf_j^i
k!1i=1∑k(−1)k−is(k,i)j=0∑nfji
1
k
!
∑
i
=
1
k
(
−
1
)
k
−
i
s
(
k
,
i
)
g
n
,
i
\dfrac{1}{k!}\sum\limits_{i=1}^k(-1)^{k-i}s(k,i)g_{n,i}
k!1i=1∑k(−1)k−is(k,i)gn,i
1
k
!
∑
i
=
1
k
(
−
1
)
k
−
i
s
(
k
,
i
)
(
∑
p
=
0
i
(
i
p
)
A
p
B
i
−
p
1
−
(
α
p
β
i
−
p
)
n
+
1
1
−
α
p
β
i
−
p
)
\dfrac{1}{k!}\sum\limits_{i=1}^k(-1)^{k-i}s(k,i)(\sum\limits_{p=0}^i\binom{i}{p}A^pB^{i-p}\dfrac{1-(\alpha^{p}\beta^{i-p})^{n+1}}{1-\alpha^p\beta^{i-p}})
k!1i=1∑k(−1)k−is(k,i)(p=0∑i(pi)ApBi−p1−αpβi−p1−(αpβi−p)n+1)
小提示:
记得特判等比数列公比为
1
1
1。
代码
#include<cstdio>
#define ll long long
#define mo 998244353
using namespace std;
const int K = 550;
int gen;
int T, op, k;
ll C[K][K], S[K][K], l, r;
ll ksm(ll x, ll y) {
ll re = 1;
while (y) {
if (y & 1) re = re * x % mo;
x = x * x % mo; y >>= 1;
}
return re;
}
struct complex {
ll x, y;
complex(ll a = 0, ll b = 0) {
x = a; y = b;
}
}A, B, alpha, beta;//x+sqrt{y}
complex operator +(complex x, complex y) {
return (complex){(x.x + y.x) % mo, (x.y + y.y) % mo};
}
complex operator -(complex x) {return (complex){(mo - x.x) % mo, (mo - x.y) % mo};}
complex operator -(complex x, complex y) {return x + (-y);}
complex operator *(complex x, complex y) {
return (complex){(x.x * y.x + gen * x.y * y.y) % mo, (x.x * y.y + x.y * y.x) % mo};
}
complex inv(complex x) {
ll fm = ksm((((x.x * x.x - gen * x.y * x.y) % mo + mo) % mo) % mo, mo - 2);
return (complex){x.x * fm % mo, (mo - x.y) * fm % mo};
}
complex ksm(complex x, ll y) {
complex re = complex(1, 0);
while (y) {
if (y & 1) re = re * x;
x = x * x; y >>= 1;
}
return re;
}
void Init() {
C[0][0] = 1;
for (int i = 1; i < K; i++) {
C[i][0] = 1; for (int j = 1; j < K; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mo;
}
S[0][0] = 1;
for (int i = 1; i < K; i++) {
for (int j = 1; j < K; j++)
S[i][j] = (S[i - 1][j - 1] + (i - 1) * S[i - 1][j] % mo) % mo;
}
gen = (op == 2) ? 5 : 3;
if (op == 2) {
A = (complex){0, ksm(5, mo - 2)}; alpha = (complex){ksm(2, mo - 2), ksm(2, mo - 2)};
B = (complex){0, (mo - ksm(5, mo - 2)) % mo}; beta = (complex){ksm(2, mo - 2), (mo - ksm(2, mo - 2)) % mo};
}
if (op == 3) {
A = (complex){ksm(2, mo - 2), ksm(6, mo - 2)}; alpha = (complex){2, 1};
B = (complex){ksm(2, mo - 2), (mo - ksm(6, mo - 2)) % mo}; beta = (complex){2, mo - 1};
}
}
ll slove(ll n) {
ll ans = 0, jc = 1; ll di = ((k & 1) ? 1 : mo - 1);
for (int i = 1; i <= k; i++, di = mo - di) {
complex sum; jc = jc * i % mo;
for (int p = 0; p <= i; p++) {
complex alphabeta = ksm(alpha, p) * ksm(beta, i - p);
//你是一个一个一个特判啊啊啊!!!
if (alphabeta.x == 1 && alphabeta.y == 0) {//特判公比为1的情况
sum = sum + ((complex){C[i][p], 0} * ksm(A, p) * ksm(B, i - p) * (complex){(n + 1) % mo, 0});
continue;
}
sum = sum + ((complex){C[i][p], 0} * ksm(A, p) * ksm(B, i - p) * ((complex){1, 0} - ksm(alphabeta, n + 1)) * inv((complex){1, 0} - alphabeta));
}
if (sum.y) {printf("f\n"); return -1;}
(ans += di * S[k][i] % mo * sum.x % mo) %= mo;
}
return ans * ksm(jc, mo - 2) % mo;
}
int main() {
scanf("%d %d", &T, &op);
Init();
while (T--) {
scanf("%lld %lld %d", &l, &r, &k); ll sz = (r - l + 1) % mo;
if (op == 2) l++, r++;
else l = (l + 1) / 2, r = r / 2;
printf("%lld\n", (slove(r) - slove(l - 1) + mo) % mo * ksm(sz, mo - 2) % mo);
}
return 0;
}