【luogu P5320】勘破神机(数学)(数列特征方程)(第一类斯特林数)

勘破神机

题目链接:luogu P5320

题目大意

给你 l , r , k l,r,k l,r,k(其中 l , r l,r l,r 很大, k ≤ 501 k\leq 501 k501),求:
1 r − l + 1 ∑ i = l r C f i k \dfrac{1}{r-l+1}\sum\limits_{i=l}^rC_{f_i}^k rl+11i=lrCfik
1 r − l + 1 ∑ i = l r C g i k \dfrac{1}{r-l+1}\sum\limits_{i=l}^rC_{g_i}^k rl+11i=lrCgik
f n f_n fn 为一个 2 ∗ n 2*n 2n 的网格往里面放 1 ∗ 2 1*2 12 的块填满的方案, g n g_n gn 则是一个 3 ∗ n 3*n 3n 的网格。

思路

首先 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=fi1+fi2,然后可以表示成那个带根号的通式嘛。

然后我们通过特征方程这个东西,我们知道如果有一个二阶递推式,我们可以把它表示成一个通项公式。
于是开始了下面的步骤:

2

f i = f i − 1 + f i − 2 f_i=f_{i-1}+f_{i-2} fi=fi1+fi2
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(215 )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 ,β=215

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 rl+1 要用之前的值)

于是进行思考,发现可以新放进来一个 2 ∗ 3 2*3 23 的,然后有 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=3fi1+2(fi2+fi3+...)
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=3fi1+2(j=0i2fj)
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) fi1=3fi2+2(j=0i3fj)
f i − f i − 1 = 3 f i − 1 − f i − 2 f_i-f_{i-1}=3f_{i-1}-f_{i-2} fifi1=3fi1fi2
f i = 4 f i − 1 − f i − 2 f_i=4f_{i-1}-f_{i-2} fi=4fi1fi2

搞出了二阶递推式,就直接开始求通项公式吧!

f i − 4 f i − 1 + f i − 2 = 0 f_i-4f_{i-1}+f_{i-2}=0 fi4fi1+fi2=0
x 2 − 4 x + 1 = 0 x^2-4x+1=0 x24x+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=2423
x 1 = 2 + 3 , x 2 = 2 − 3 x_1=2+\sqrt{3},x_2=2-\sqrt{3} x1=2+3 ,x2=23
带入 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(23 )=3

A ( 2 + 3 ) + ( 1 − A ) ( 2 − 3 ) = 3 A(2+\sqrt3)+(1-A)(2-\sqrt3)=3 A(2+3 )+(1A)(23 )=3
A ( 2 + 3 ) + 2 − 3 − A ( 2 − 3 ) = 3 A(2+\sqrt3)+2-\sqrt{3}-A(2-\sqrt3)=3 A(2+3 )+23 A(23 )=3
2 3 A = 1 + 3 2\sqrt3A=1+\sqrt3 23 A=1+3
A = 1 + 3 2 3 = 3 + 3 6 A=\dfrac{1+\sqrt3}{2\sqrt3}=\dfrac{\sqrt3+3}{6} A=23 1+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=633
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+633 (2423 )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=633 ,β=2423
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=633 ,β=23


于是我们似乎把 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=0n(kfi)
∑ i = 0 n f i ! k ! ( f i − k ) ! \sum\limits_{i=0}^n\dfrac{f_i!}{k!(f_i-k)!} i=0nk!(fik)!fi!
∑ i = 0 n f i k ‾ k ! \sum\limits_{i=0}^n\dfrac{f_i^{\underline k}}{k!} i=0nk!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=0nj=1k(1)kjs(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=1ks(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=1k(1)kis(k,i)j=0nfji

g n , j = ∑ i = 0 n f i j g_{n,j}=\sum\limits_{i=0}^nf_i^j gn,j=i=0nfij
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=0n(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=0j(kj)i=0n(Aαi)k(Bβi)jk
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=0j(kj)AkBjki=0nαikβi(jk)
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=0j(kj)AkBjk1αkβjk1α(n+1)kβ(n+1)(jk)(等比数列求和)

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=1k(1)kis(k,i)j=0nfji
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=1k(1)kis(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=1k(1)kis(k,i)(p=0i(pi)ApBip1αpβip1(αpβip)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;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值