洛谷题面传送门

神仙题(为什么就没能自己想出来呢/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. 免费UML工具介绍 - 基于云技术

    现在,我们的时间很短,无法完成我们的项目.我们不想花时间在软件配置.安装上,而是集中精力解决问题,对吗? 今天我想给大家介绍一个非常特殊的IT专业人员工具.软件开发.战略分析.客户行程映射等灵活的免费 ...

  2. 手把手教你学Dapr - 2. 必须知道的概念

    Sidecar 边车 Dapr API提供Http和gRPC两种通讯方式. 运行方式则可以是容器也可以是进程(Windows开发推荐使用Self Hosted,后续会解释). 这样的好处是与运行环境无 ...

  3. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  4. Java 将Excel转为et和ett格式

    以.et结尾的文件格式是属于金山办公软件WPS Office中的电子表格文件,.ett是一种模板文件格式.除了通过WPS软件可以创建该格式的电子表格外,也可以通过格式转换的方法来获得,如将Micros ...

  5. hdu 3047 Zjnu Stadium(并查集)

    题意: 300个座位构成一个圈. 有N个人要入座. 共有M个说明 :A B X ,代表B坐在A顺时针方向第X个座位上.如果这个说明和之前的起冲突,则它是无效的. 问总共有多少个无效的. 思路: 并查集 ...

  6. 关于dns服务工作的原理,和配置的细节理解。

    dns服务器相关 1,dns原理,也就是迭代,和递归查询.将域名解析为ip的过程. 一次完整的查询请求经过的流程: Client -->hosts文件 -->DNS Service Loc ...

  7. 【动图解释】关系数据库de关系代数小记

    本文章在 Github 撰写,同时在 我的博客 进行了发布. 最近学数据库概论学到了关系数据库的关系代数了.哎嘛,真的把我整晕了,尤其是关系代数的使用,很容易让人被蒙在鼓里. 对我来说槽点最大的莫过于 ...

  8. Kafka 消费迟滞监控工具 Burrow

    Kafka 官方对于自身的 LAG 监控并没有太好的方法,虽然Kafka broker 自带有 kafka-topic.sh, kafka-consumer-groups.sh, kafka-cons ...

  9. Mac sourceTree每次都输入密码

    打开终端 依次输入以下三条命令 curl http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain - ...

  10. 力扣 - 剑指 Offer 06. 从尾到头打印链表.md

    题目 剑指 Offer 06. 从尾到头打印链表 思路1(递归) 首先先遍历整个脸表,计算出链表的长度(用于初始化数组).然后进行递归,从链表头部递归到尾部,这期间什么都不做,直到递归到最后一个节点的 ...