洛谷题面传送门

神仙题(为什么就没能自己想出来呢/zk/zk)

这是我 AC 的第 \(2\times 10^3\) 道题哦

首先考虑 \(m=2\) 的情况,我们首先可以想到一个非常 trivial 的 DP:\(dp_i\) 表示填好前 \(i\) 列的方案数,那么第 \(i\) 列显然有横着放和竖着放两种可能,方案数分别是 \(dp_{i-2}\) 和 \(dp_{i-1}\),因此我们有 \(dp_i=dp_{i-2}+dp_{i-1}\),边界条件 \(dp_0=1\),显然这个递推式与斐波那契数列有非常紧密的联系,具体来说 \(dp_i=f_{i+1}\)。因此我们可以将 \(L,R\) 分别加一,那么答案可以表示成:

\[ans=\sum\limits_{i=L}^R\dbinom{f_i}{k}
\]

一脸不好用正常方法维护的样子。

不过注意到对于斐波那契数列而言我们有一个通项公式 \(f_i=\dfrac{1}{\sqrt{5}}((\dfrac{1+\sqrt{5}}{2})^n-(\dfrac{1-\sqrt{5}}{2})^n)\),因此我们考虑在这个通项公式上做点手脚。方便起见下文中记 \(A=\dfrac{1}{\sqrt{5}},B=-\dfrac{1}{\sqrt{5}},X=\dfrac{1+\sqrt{5}}{2},Y=\dfrac{1-\sqrt{5}}{2}\),那么 \(f_i=AX^i+BY^i\)。有人会说,这 \(\sqrt{5}\) 无理数都出来了,况且 \(\sqrt{5}\) 还在组合数上指标上,那不是更不好维护了吗?别急,\(\sqrt{5}\) 这样的无理数确实和阶乘幂不太搭,不过别忘了我们还有个阶乘幂转下降幂的公式:\(x^{\underline{k}}=\sum\limits_{i=0}^k\begin{bmatrix}k\\i\end{bmatrix}(-1)^{k-i}x^i\),因此 \(\dbinom{f_i}{k}=\dbinom{1}{k!}f_i^{\underline{k}}=\dfrac{1}{k!}\sum\limits_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}f_i^j\),因此我们有:

\[\begin{aligned}
ans&=\sum\limits_{i=L}^R\dbinom{f_i}{k}\\
&=\dfrac{1}{k!}\sum\limits_{i=L}^R\sum\limits_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}f_i^j\\
&=\dfrac{1}{k!}\sum\limits_{i=L}^R\sum\limits_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}(AX^i+BY^i)^j\\
&=\dfrac{1}{k!}\sum\limits_{i=L}^R\sum\limits_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}\sum\limits_{p=0}^j\dbinom{j}{p}(AX^i)^p(BY^i)^{j-p}\\
&=\dfrac{1}{k!}\sum\limits_{j=0}^k\begin{bmatrix}k\\j\end{bmatrix}(-1)^{k-j}\sum\limits_{p=0}^j\dbinom{j}{p}A^pB^{j-p}\sum\limits_{i=L}^R(X^pY^{j-p})^i
\end{aligned}
\]

前面都可以在 \(\mathcal O(k^2)\) 时间内枚举得出,后面可以一波等比数列求和公式带走,时间复杂度 \(k^2\log R\)。

有几个细节需要注意:

  • 注意特判 \(X^pY^{j-p}=1\) 的情况
  • 由于 \(5\) 在 \(\bmod 998244353\) 意义下无二次剩余(凉 心 出 题 人),因此我们需要像二次剩余那样将数域由 \(\mathbb{R}\) 扩展到 \(\mathbb{Z}_5=\{a+b\sqrt{5}|a,b\in\mathbb{R}\}\)(瞎起名字 ing),加减乘除照样定义,这样就可以避免这个问题了。

这个故事告诉我们,有时候遇到斐波那契数列有关的题,即使模数不那么友好也能套通项公式/ts

接下来考虑 \(m=3\),首先 \(n\) 是奇数的情况答案肯定是 \(0\),我们 duck 不必管他们。对于 \(n\) 是偶数的情况咱们还是先从最 naive 的 DP 入手,那么最后一列可以三个横着的 \(1\times 2\) 多米诺骨牌,方案数 \(dp_{i-2}\),也可以是第一行放一个横着的骨牌,下面两列各放一个竖着的骨牌,当然也可以 reverse 一下,横着的骨牌放在第三行,方案数 \(2dp_{i-2}\),还可以第一行来一个横着的骨牌,紧接着下面跟着一个竖着的骨牌,紧接着左边又是 \(2k(k\in[1,\infty)\cap\mathbb{Z})\) 个横着的骨牌,最后又一个竖着的,那么此时应从 \(dp_{i-2k-2}\) 转移过来,方案数 \(2dp_{i-2k-2}\),因此我们有

\[dp_i=3dp_{i-1}+2\sum\limits_{j=2k,k\ge 2}dp_{i-j}
\]

前缀和搞搞可以变成:

\[dp_i=4dp_{i-2}-dp_{i-4}
\]

如果我们设 \(g_n=dp_{2n}\),那么上式可写作 \(g_i=4g_{i-1}-g_{i-2}\)。

喜闻乐见的 \(a_i=Aa_{i-1}+Ba_{i-2}\) 的形式,列出特征根方程 \(1=4x-x^2\),解出它的两个根为 \(x_1=2+\sqrt{3},x_2=2-\sqrt{3}\),然后套个待定系数法,设 \(g_i=Ax_1^i+Bx_2^i\),那么:

\[\begin{cases}
A+B=1\\
(2+\sqrt{3})A+(2-\sqrt{3})B=3
\end{cases}
\]

解得

\[\begin{cases}
A=\dfrac{3+\sqrt{3}}{6}\\
B=\dfrac{3-\sqrt{3}}{6}
\end{cases}
\]

然后就和 \(m=2\) 的情况一样了。

然鹅由于太久没有接触普通幂与阶乘幂之间的转换,一开始甚至把第一类斯特林数敲成了第二类斯特林数……这里稍微澄清一下:

  • 用阶乘幂表示普通幂用第二类斯特林数,以等式 \(x^k=\sum\limits_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}x^{\underline{i}}\) 为例,如果我们把等号左右两边叫做一区和二区,那么下划线在哪个区就用第几类斯特林数。
  • 用大幂表示小幂需要加 \((-1)^{k-i}\)
const int MAXK=501;
const int MOD=998244353;
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int fac[MAXK+5],ifac[MAXK+5],s[MAXK+5][MAXK+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
s[0][0]=1;for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) s[i][j]=(s[i-1][j-1]+1ll*(i-1)*s[i-1][j])%MOD;
}
int sq;
struct comp{
int x,y;
comp(int _x=0,int _y=0):x(_x),y(_y){}
comp operator +(const comp &rhs){return comp((x+rhs.x)%MOD,(y+rhs.y)%MOD);}
comp operator -(const comp &rhs){return comp((x-rhs.x+MOD)%MOD,(y-rhs.y+MOD)%MOD);}
comp operator *(const comp &rhs){return comp((1ll*x*rhs.x+1ll*y*rhs.y%MOD*sq)%MOD,(1ll*x*rhs.y+1ll*y*rhs.x)%MOD);}
comp operator /(const comp &rhs){
ll inv=qpow((1ll*rhs.x*rhs.x%MOD-1ll*sq*rhs.y%MOD*rhs.y%MOD+MOD)%MOD,MOD-2);
return comp(1ll*(1ll*x*rhs.x%MOD-1ll*y*rhs.y%MOD*sq%MOD+MOD)*inv%MOD,1ll*(1ll*y*rhs.x%MOD-1ll*x*rhs.y%MOD+MOD)*inv%MOD);
}
bool operator ==(const comp &rhs){return (!(x^rhs.x)&&!(y^rhs.y));}
} A,B,X,Y;
int binom(int x,int y){return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;}
comp qpow_c(comp x,ll e){
comp res(1);
for(;e;e>>=1,x=x*x) if(e&1) res=res*x;
return res;
}
comp getsum(comp bs,ll t){
if(t<0) return comp();
if(bs==comp(1)) return comp((t+1)%MOD,0);
return (qpow_c(bs,t+1)-comp(1))/(bs-comp(1));
}
comp getsum(comp bs,ll l,ll r){return getsum(bs,r)-getsum(bs,l-1);}
int solve(ll l,ll r,int k){
if(l>r) return 0;comp res;
for(int j=0;j<=k;j++){
comp sum=comp();
for(int p=0;p<=j;p++){
comp mul(1);
mul=mul*comp(binom(j,p))*qpow_c(A,p)*qpow_c(B,j-p);
mul=mul*getsum(qpow_c(X,p)*qpow_c(Y,j-p),l,r);
sum=sum+mul;
} sum=sum*comp(s[k][j]);
// printf("%d %d\n",sum.x,sum.y);
if((k-j)&1) res=res-sum;
else res=res+sum;
} return 1ll*res.x*ifac[k]%MOD;
}
int main(){
int qu,opt;scanf("%d%d",&qu,&opt);init_fac(MAXK);
if(opt==2){
sq=5;A=comp(0,1)/comp(5);B=comp(0,MOD-1)/5;
X=comp(1,1)/comp(2);Y=comp(1,MOD-1)/comp(2);
} else {
sq=3;A=comp(3,1)/comp(6);B=comp(3,MOD-1)/comp(6);
X=comp(2,1);Y=comp(2,MOD-1);
} while(qu--){
ll l,r;int k;scanf("%lld%lld%d",&l,&r,&k);
if(opt==2) printf("%d\n",1ll*qpow((r-l+1)%MOD,MOD-2)*solve(l+1,r+1,k)%MOD);
else printf("%d\n",1ll*qpow((r-l+1)%MOD,MOD-2)*solve(l+1>>1,r>>1,k)%MOD);
}
return 0;
}

题解 P5320 - [BJOI2019]勘破神机(推式子+第一类斯特林数)的更多相关文章

  1. luogu P5320 [BJOI2019]勘破神机

    传送门 首先我们要知道要求什么.显然每次放方块要放一大段不能从中间分开的部分.设\(m=2\)方案为\(f\),\(m=3\)方案为\(g\),\(m=2\)可以放一个竖的,或者两个横的,所以\(f_ ...

  2. [BJOI2019]勘破神机

    [BJOI2019]勘破神机 推式子好题 m=2,斐波那契数列,$f_{n+1}$项 不妨$++l,++r$,直接求$f_n$ 求$\sum C(f_n,k)$,下降幂转化成阶乘幂,这样都是多项式了, ...

  3. [BJOI2019]勘破神机(斯特林数,数论)

    [BJOI2019]勘破神机(斯特林数,数论) 题面 洛谷 题解 先考虑\(m=2\)的情况. 显然方案数就是\(f_i=f_{i-1}+f_{i-2}\),即斐波那契数,虽然这里求出来是斐波那契的第 ...

  4. [BJOI2019]勘破神机(斯特林数+二项式定理+数学)

    题意:f[i],g[i]分别表示用1*2的骨牌铺2*n和3*n网格的方案数,求ΣC(f(i),k)和ΣC(g(i),k),对998244353取模,其中l<=i<=r,1<=l< ...

  5. #loj3090 [BJOI2019] 勘破神机

    简单线性代数练习题 首先翻开具体数学生成函数一章,可以发现\(F(n),G(n)\)满足以下递推式 \[F(n)=F(n-1)+F(n-2),F(0)=1,F(1)=1\] \[G(n)=4G(n-2 ...

  6. [BJOI2019]勘破神机(第一类斯特林数,斐波那契数列)

    真的是好题,只不过强行多合一有点过分了…… 题目大意: $T$ 组数据.每个测试点中 $m$ 相同. 对于每组数据,给定 $l,r,k$,请求出 $\dfrac{1}{r-l+1}\sum\limit ...

  7. 【LOJ】#3090. 「BJOI2019」勘破神机

    LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...

  8. LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域

    题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...

  9. loj 3090 「BJOI2019」勘破神机 - 数学

    题目传送门 传送门 题目大意 设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网 ...

随机推荐

  1. css单位px,em,rem区别

    在css中单位长度用的最多的是px.em.rem,这三个的区别是: px是固定的像素,一旦设置了就无法因为适应页面大小而改变. em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定 ...

  2. 3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项

    3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项 The diagram below shows the essential ...

  3. ES2020新特性记录

    1.可选链操作符 // oldlet ret = obj && obj.first && obj.first.second// newlet ret = obj?.fi ...

  4. MAC 安装 apache ab 压力测试工具以及遇到的坑

    ab 是apache对 http服务器进行压力测试的工具,它可以测试出服务器每秒可以处理多少请求.本文记录mac版本安装 ab 的步骤以及遇到的坑. 下载 进入 apache ab官网 下载页面. 安 ...

  5. AtCoder Beginner Contest 224

    AtCoder Beginner Contest 224 A - Tires 思路分析: 判断最后一个字符即可. 代码如下: #include <bits/stdc++.h> using ...

  6. spring security整合QQ登录

    最近在了解第三方登录的内容,尝试对接了一下QQ登录,此次记录一下如何实现QQ登录的过程,在这个例子中是和spring secuirty整合的,不整合spring secuirty也是一样的. 需求: ...

  7. Noip模拟79 2021.10.17(题目名字一样)

    T1 F 缩点缩成个$DAG$,然后根据每个点的度数计算期望值 1 #include<cstdio> 2 #include<cstring> 3 #include<vec ...

  8. 你知道怎么从jar包里获取一个文件的内容吗

    目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...

  9. 连续子序列的最大和 牛客网 剑指Offer

    连续子序列的最大和 牛客网 剑指Offer 题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量 ...

  10. cf 11B Jumping Jack(贪心,数学证明一下,,)

    题意: 给一个数X. 起始点为坐标0.第1步跳1格,第2步跳2格,第3步跳3格,.....以此类推. 每次可以向左跳或向右跳. 问最少跳几步可以到坐标X. 思路: 假设X是正数. 最快逼近X的方法是不 ...