[BJOI2019]勘破神机(斯特林数,数论)
[BJOI2019]勘破神机(斯特林数,数论)
题面
题解
先考虑\(m=2\)的情况。
显然方案数就是\(f_i=f_{i-1}+f_{i-2}\),即斐波那契数,虽然这里求出来是斐波那契的第\(n+1\)项,但是本质上没什么区别,就默认是斐波那契数列了。
斐波那契数列的特征根是\(\alpha=\frac{1+\sqrt 5}{2},\beta=\frac{1-\sqrt 5}{2}\),然后大力设一下通项是\(f_n=A\alpha^n+B\beta^n\),可以解出\(f_n=\frac{1}{\sqrt 5}\alpha^n-\frac{1}{\sqrt 5}\beta^n\)。
而要求的东西就是\(\displaystyle \sum_{i=l}^r {f_i\choose k}\),本质上就是要求\(\frac{1}{K!}f_i^{\underline k}\)。
这个东西直接拿第一类斯特林数展开\(\displaystyle \sum_j\sum_{i=0}^k \begin{bmatrix}k\\ i\end{bmatrix}f_j^k(-1)^{k-i}\)。
把斐波那契的通项直接带进去,得到:\(\displaystyle \sum_{i=0}^k\begin{bmatrix}k\\ i\end{bmatrix}(-1)^{k-i}\sum_{j}(A\alpha^j+B\alpha^j)^i\)。
后面那个东西再拆一步就是\(\displaystyle \sum_{j=0}^i{i\choose j}(A\alpha^n)^j(B\beta^n)^{i-j}\),
带回去交换求和顺序之后得到:\(\displaystyle \sum_{k=0}^K(-1)^{K-k}\begin{bmatrix}K\\k\end{bmatrix}\sum_{i=0}^k{k\choose i}A^iB^{k-i}\sum_{j=L}^R \alpha^{ji}\beta^{j(k-i)}\)。
后面一个部分显然是等比数列可以直接计算,这样子我们就把复杂度做到了\(O(k^2)\)。
现在考虑\(m=3\)的情况,现在要做的显然就是把通项给求出来。
首先\(n\)为奇数的时候显然无解。
考虑为偶数的时候,令\(g_i\)表示第\(i\)个偶数的时候的答案,那么为了防止重复计算,我们需要找到一个放置方法满足在偶数位置一定不会恰好放满,发现这样子一定是在第一行竖着放一个横着放一个,然后后面每次都强制横着放跨过偶数位置,这里的贡献是\(\displaystyle \sum_{j=0}^{i-2}2g_j\),然后\(g_{i-1}\)的贡献比较特殊是\(3\),因为这个位置可以不用强制跨过奇数位置,所以可以任意的放满\(3*2\)的格子,因此转移可以写成:\(\displaystyle g_i=g_{i-1}+2\sum_{j=0}^{i-1}g_j\)。
然后写两个出来差分:
g_{i+1}=g_i+2\sum_{j=0}^i g_j\end{cases}\]
推出\(g_{i+1}-g_i=3g_i-g_{i-1}\),推出递推式\(g_{i+1}=4g_i-g_{i-1}\)。
然后特征方程:\(x^2-4x+1=0\),两个解:\(2\pm \sqrt 3\)。
然后待定系数解出来通项是:\(\displaystyle g_n=\frac{3+\sqrt 3}{6}(2+\sqrt 3)^n+\frac{3-\sqrt 3}{6}(2-\sqrt 3)^n\)。
然后就和前面的东西类似了。
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
const int MOD=998244353;
#define inv2 499122177
#define inv5 598946612
#define inv6 166374059
inline ll read()
{
ll x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int fpow(int a,ll b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int S[505][505],C[505][505];ll V;
struct Num{int a,b;}z;
Num operator+(Num a,Num b){return (Num){(a.a+b.a)%MOD,(a.b+b.b)%MOD};}
Num operator-(Num a,Num b){return (Num){(a.a+MOD-b.a)%MOD,(a.b+MOD-b.b)%MOD};}
Num operator*(Num a,Num b){return (Num){(1ll*a.a*b.a+V*a.b*b.b)%MOD,(1ll*a.b*b.a+1ll*a.a*b.b)%MOD};}
Num operator*(Num a,int b){return (Num){1ll*a.a*b%MOD,1ll*a.b*b%MOD};}
Num fpow(Num a,ll b){Num s=(Num){1,0};while(b){if(b&1)s=s*a;a=a*a;b>>=1;}return s;}
int m,K;ll L,R;
Num Inv(Num a){return (Num){a.a,(MOD-a.b)%MOD}*fpow((1ll*a.a*a.a+MOD-V*a.b*a.b%MOD)%MOD,MOD-2);}
int main()
{
int T=read();m=read();if(m==2)V=5;else V=3;
while(T--)
{
L=read();R=read();K=read();
S[0][0]=1;
for(int i=1;i<=K;++i)
for(int j=1;j<=i;++j)
S[i][j]=(S[i-1][j-1]-1ll*S[i-1][j]*(i-1)%MOD+MOD)%MOD;
for(int i=0;i<=K;++i)C[i][0]=1;
for(int i=1;i<=K;++i)
for(int j=1;j<=i;++j)C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
Num alpha,beta,A,B;ll QwQ=R-L+1;
if(m==2)
{
++L;++R;
alpha=(Num){inv2,inv2},beta=(Num){inv2,MOD-inv2};
A=(Num){0,inv5},B=(Num){0,MOD-inv5};
}
else
{
R=R>>1;L=(L+1)>>1;
alpha=(Num){2,1},beta=(Num){2,MOD-1};
A=(Num){inv2,inv6},B=(Num){inv2,MOD-inv6};
}
int ans=0;ll t=R-L;
for(int i=0;i<=K;++i)
{
Num ret=z;
for(int j=0;j<=i;++j)
{
Num s=fpow(A,j)*fpow(B,i-j)*C[i][j];
Num p=fpow(fpow(alpha,L),j)*fpow(fpow(beta,L),(i-j));
Num q=fpow(alpha,j)*fpow(beta,i-j);
Num w=p*((fpow(q,t+1)-(Num){1,0})*Inv(q-(Num){1,0}));
if(q.a==1&&q.b==0)w=p*((R-L+1)%MOD);
ret=ret+s*w;
}
ans=(ans+1ll*ret.a*S[K][i])%MOD;
}
int Ans=1ll*ans*fpow(QwQ%MOD,MOD-2)%MOD;
for(int i=1;i<=K;++i)Ans=1ll*Ans*fpow(i,MOD-2)%MOD;
printf("%d\n",Ans);
}
return 0;
}
[BJOI2019]勘破神机(斯特林数,数论)的更多相关文章
- LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域
题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...
- [BJOI2019]勘破神机
[BJOI2019]勘破神机 推式子好题 m=2,斐波那契数列,$f_{n+1}$项 不妨$++l,++r$,直接求$f_n$ 求$\sum C(f_n,k)$,下降幂转化成阶乘幂,这样都是多项式了, ...
- [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< ...
- 题解 P5320 - [BJOI2019]勘破神机(推式子+第一类斯特林数)
洛谷题面传送门 神仙题(为什么就没能自己想出来呢/zk/zk) 这是我 AC 的第 \(2\times 10^3\) 道题哦 首先考虑 \(m=2\) 的情况,我们首先可以想到一个非常 trivial ...
- [BJOI2019]勘破神机(第一类斯特林数,斐波那契数列)
真的是好题,只不过强行多合一有点过分了…… 题目大意: $T$ 组数据.每个测试点中 $m$ 相同. 对于每组数据,给定 $l,r,k$,请求出 $\dfrac{1}{r-l+1}\sum\limit ...
- luogu P5320 [BJOI2019]勘破神机
传送门 首先我们要知道要求什么.显然每次放方块要放一大段不能从中间分开的部分.设\(m=2\)方案为\(f\),\(m=3\)方案为\(g\),\(m=2\)可以放一个竖的,或者两个横的,所以\(f_ ...
- #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 ...
- 【LOJ】#3090. 「BJOI2019」勘破神机
LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...
- [Luogu5320][BJOI2019]堪破神机(DP+斯特林数)
https://www.cnblogs.com/cjyyb/p/10747543.html 特征方程+斯特林反演化简式子,要注意在模998244353意义下5没有二次剩余,所以每个数都要用$a+b\s ...
随机推荐
- SqlSugar ORM 入门篇2 【查询】 让我们实现零SQL
SqlSugar在查询的功能是非常强大的,多表查询.分页查询 . 一对一查询.二级缓存.一对多查.WhenCase等复杂函数.Mapper功能.和拉姆达自定义扩展等,用好了是可以做到真正零SQL的一款 ...
- Java设计模式---桥接Bridge模式
参考于 : 大话设计模式 马士兵设计模式视频 写在开头: 桥接模式主要用于一件事物分成了两个维度,进行排列组合,比如礼物,可以分成优雅的礼物(抽象),花(具体),排列组合优雅的花! 1.为什么使用桥接 ...
- webpack 单独打包指定JS文件(CopyWebpackPlugin)
背景: 不确定打出的前端包所访问的后端IP,需要对项目中IP配置文件单独拿出来,方便运维部署的时候对IP做修改.因此,需要用webpack单独打包指定文件.npm install --save-dev ...
- 三、Snapman多人协作电子表格之——软件的基本功能
Snapman多人协作电子表格是一个即时工作系统. 一.SnapmanServer服务端 SnapmanServer服务端在安装Snapman软件一起自带,是一个小巧的控制台程序SnapmanServ ...
- Windows下建立ArcGIS Server集群
原创文章,转载须标明出处自: http://www.cnblogs.com/gisspace/p/8269525.html -------------------------------------- ...
- 关于Android中ION的libion
在高通的OpenCL SDK中,其Android.mk文件中,有判断当前kernel的版本,如果大于4.12,那么就使用libion.so,否则则使用ion kernle uapi: # Tries ...
- 关于Android Studio 3.2 运行应用时提示 “Instant Run requires that the platform corresponding to your target device (Android 7.0 (Nougat)) is installed.” 的说明
点击"Run",运行App后,Android Studio显示如图1-1界面: 图1-1 这是因为你连接的外部设备(比如Android手机或AVD)的SDK版本在你的电脑上没有安装 ...
- webstorm2018.1 汉化
https://github.com/pingfangx/TranslatorX 这个百度云 选择webstorm 选择勾选的文件 选择你下载webstorm 的版本 我下载的是2018.1的 之后等 ...
- ubuntu如何安装chromium浏览器并设置成中文版
在Ubuntu上使用APT安装Chromium有3种方法: 1.在Ubuntu软件中心输入chromium,然后在结果中选择安装即可. 2.在新立得软件包管理器中输入chromium,然后标记安装即可 ...
- 一个简易的kmp教学并给出java实现
简单介绍一下问题 给定source字符串,找出target字符串出现的首位 例如 source 为“abddabddabc” target 为 “abddabc” 从第一位开始比较 |a b d ...