#loj3090 [BJOI2019] 勘破神机
简单线性代数练习题
首先翻开具体数学生成函数一章,可以发现\(F(n),G(n)\)满足以下递推式
\]
\]
我们发现\(G\)只有偶数项有值(证明的话可以把网格黑白染色什么的来证明)
那么我们可以设\(T(n)=G(2n)\)
那么\(T\)服从以下递推式
\]
那么我们发现\(F\)和\(G\)是两个二阶常系数线性递推数列
根据特征方程和生成函数那一套理论,我们可以知道\(F,T\)都有这样的通项公式
\]
考虑题目让我们算什么
\]
众所周知,组合数是个\(O(k)\)阶的多项式,那么我们现在的问题就变成了快速求
\]
那么稍微画一下式子就是
\]
暴力二项式定理展开
\]
稍微交换一下求和号
\]
后面显然是个等比数列求和,可以\(O(logn)\)的算出
那么这题就做完了,复杂度\(O(Tk^2logn)\)
注意当\(m=3\)的时候,你需要将输入的区间缩一下,因为询问的是\(G\)但是我们的做法只能处理\(T\)
另外你可能需要将输入的区间加加减减,因为我们的公式一般认为\(F(0)=1\)
下面是简单的线性代数内容,是关于如何解出\(A,B,C,D\)的
对于F显然是fib数列的通项公式,你应该熟练的背过它
\]
\]
\]
\]
对于\(T\)稍微解一下特征方程可以得到
\]
\]
那么我们令\(T(1)=1,T(2)=1\),就可以通过待定系数法解出\(C,D\)来
可能涉及到\(\sqrt{3}\)的方程组会有点复杂,推荐的解法是
令\(x=C+D,y=\sqrt{3}(C-D)\)
然后你会发现方程组干净了很多,从而我们可以解出x和y来,借助x和y就可以还原C,D了
解得
\]
最后一个问题是5和3在膜998244353剩余系下统统没有二次剩余
把每个数字表示成\(r+v\sqrt{k}\)的形式即可实现模意义复数,然后就能计算了
等比数列求和涉及除法,使用这种复数实现除法的时候用分母有理化推个式子就行了
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
using namespace std;const int N=1e5+10;
typedef unsigned long long ll;const ll mod=998244353;
inline ll po(ll a,ll p){ll r=1;for(;p;p>>=1,a=a*a%mod)if(p&1)r=r*a%mod;return r;}
# define md(x) (x=(x>=mod)?x-mod:x)
ll sqr;
struct cmp
{
ll r;ll v;
cmp(ll R=0,ll V=0){r=R;v=V;}
friend cmp operator +(cmp a,cmp b)
{
cmp c=cmp(a.r+b.r,a.v+b.v);
md(c.r);md(c.v);return c;
}
friend cmp operator -(cmp a,cmp b)
{
cmp c=cmp(a.r+mod-b.r,a.v+mod-b.v);
md(c.r);md(c.v);return c;
}
friend cmp operator *(cmp a,cmp b)
{
return cmp((a.r*b.r+sqr*a.v%mod*b.v)%mod,(a.r*b.v+b.r*a.v)%mod);
}
friend cmp operator /(cmp a,cmp b)
{
cmp c=a*cmp(b.r,mod-b.v);
ll iv=((b.r*b.r+(mod-sqr)*b.v%mod*b.v))%mod;
iv=po(iv,mod-2);
(c.r*=iv)%=mod;(c.v*=iv)%=mod;
return c;
}
}A,B,C,D;int T;int m;
// fib(n) =(A^n-B^n)*C
inline cmp cpo(cmp a,ll p)
{
cmp r=cmp(1,0);
for(;p;p>>=1,a=a*a)if(p&1)r=r*a;return r;
}
ll ifac[N];ll c[1010][1010];ll sr1[1010][1010];
inline void pre()
{
ifac[0]=1;ifac[1]=1;
for(int i=2;i<N;i++)
ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;
for(int i=1;i<N;i++)
(ifac[i]*=ifac[i-1])%=mod;
for(int i=0;i<1006;i++)
{
c[i][0]=c[i][i]=1;
for(int j=1;j<i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
sr1[0][0]=1;
for(int i=0;i<1006;i++)
for(int j=1;j<=i;j++)
sr1[i][j]=(sr1[i-1][j-1]+(mod-i+1)*sr1[i-1][j])%mod;
if(m==2)
{
ll iv2=(mod+1)/2;sqr=5;
A=cmp(iv2,iv2);B=cmp(iv2,mod-iv2);
C=cmp(0,po(5,mod-2));
D=cmp(C.r,mod-C.v);
}else
{
ll iv6=po(6,mod-2);sqr=3;
A=cmp(2,1);B=cmp(2,mod-1);
C=cmp(3*iv6%mod,(mod-1)*iv6%mod);
D=cmp(C.r,mod-C.v);
}
}
//mar <cmp> st;mar <cmp> trs;
inline cmp csum(cmp q,ll n)
{
if(q.r==1&&q.v==0)
return (cmp){(n+1)%mod,0};
cmp res=cpo(q,n+1)-cmp(1,0);
res=res/(q-cmp(1,0));
// printf("q=%lld,%lld,res=%lld,%lld\n",q.r,q.v,res.r,res.v);
return res;
}
inline ll cfibk(ll n,int k)
{
cmp res=cmp(0,0);
for(int j=0;j<=k;j++)
{
cmp q=cpo(A,k-j)*cpo(B,j);
cmp xs=(cmp){c[k][j],0}*cpo(C,k-j)*cpo(D,j);
res=res+xs*csum(q,n);
}
return res.r;
}
namespace solver2
{
inline void solve()
{
ll l;ll r;int k;
scanf("%lld%lld%d",&l,&r,&k);
l++;r++;ll res=0;
for(int i=1;i<=k;i++)
(res+=(cfibk(r,i)+mod-cfibk(l-1,i))*sr1[k][i])%=mod;
(res*=ifac[k])%=mod;
(res*=po((r-l+1)%mod,mod-2))%=mod;
printf("%lld\n",res);
}
}
namespace solver3
{
inline void solve()
{
ll l;ll r;int k;
scanf("%lld%lld%d",&l,&r,&k);
ll len=r-l+1;
if(l&1)l++;l/=2;
if(r&1)r--;r/=2;
l++;r++;
ll res=0;
for(int i=1;i<=k;i++)
(res+=(cfibk(r,i)+mod-cfibk(l-1,i))*sr1[k][i])%=mod;
(res*=ifac[k])%=mod;
(res*=po(len%mod,mod-2))%=mod;
printf("%lld\n",res);
}
}
int main()
{
scanf("%d%d",&T,&m);
pre();
if(m==2)
for(int z=1;z<=T;z++)
solver2::solve();
else
for(int z=1;z<=T;z++)
solver3::solve();
return 0;
}
#loj3090 [BJOI2019] 勘破神机的更多相关文章
- [BJOI2019]勘破神机(斯特林数,数论)
[BJOI2019]勘破神机(斯特林数,数论) 题面 洛谷 题解 先考虑\(m=2\)的情况. 显然方案数就是\(f_i=f_{i-1}+f_{i-2}\),即斐波那契数,虽然这里求出来是斐波那契的第 ...
- [BJOI2019]勘破神机
[BJOI2019]勘破神机 推式子好题 m=2,斐波那契数列,$f_{n+1}$项 不妨$++l,++r$,直接求$f_n$ 求$\sum C(f_n,k)$,下降幂转化成阶乘幂,这样都是多项式了, ...
- luogu P5320 [BJOI2019]勘破神机
传送门 首先我们要知道要求什么.显然每次放方块要放一大段不能从中间分开的部分.设\(m=2\)方案为\(f\),\(m=3\)方案为\(g\),\(m=2\)可以放一个竖的,或者两个横的,所以\(f_ ...
- [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< ...
- [BJOI2019]勘破神机(第一类斯特林数,斐波那契数列)
真的是好题,只不过强行多合一有点过分了…… 题目大意: $T$ 组数据.每个测试点中 $m$ 相同. 对于每组数据,给定 $l,r,k$,请求出 $\dfrac{1}{r-l+1}\sum\limit ...
- 题解 P5320 - [BJOI2019]勘破神机(推式子+第一类斯特林数)
洛谷题面传送门 神仙题(为什么就没能自己想出来呢/zk/zk) 这是我 AC 的第 \(2\times 10^3\) 道题哦 首先考虑 \(m=2\) 的情况,我们首先可以想到一个非常 trivial ...
- 【LOJ】#3090. 「BJOI2019」勘破神机
LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...
- loj 3090 「BJOI2019」勘破神机 - 数学
题目传送门 传送门 题目大意 设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网 ...
- LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域
题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...
随机推荐
- 简单rmi示例
User类 注意:需要实现序列化 package study.rmi.server; import java.io.Serializable; public class User i ...
- swift-基础语法2
一.整形 :有符号和无符号类型 有符号类型:Int ,Int8 ,Int32,Int64 无符号类型: UInt ,UInt8 UInt32,UInt64 注意点:如果你的开发环境是32位,那么Int ...
- 2018.12.31 bzoj4001: [TJOI2015]概率论(生成函数)
传送门 生成函数好题. 题意简述:求nnn个点的树的叶子数期望值. 思路: 考虑fnf_nfn表示nnn个节点的树的数量. 所以有递推式f0=1,fn=∑i=0n−1fifn−1−i(n>0) ...
- 2018.10.27 bzoj3209: 花神的数论题(数位dp)
传送门 数位dpdpdp经典题. 题面已经暗示了我们按照二进制位来数位dpdpdp. 直接dpdpdp多少个数有111个111,222个111,333个111-, 然后快速幂算就行了. 于是我们枚举前 ...
- 相似性度量 Aprioir算法
第三章 标称:转换成0,1来算,或者用非对称二元属性 二元:x1,x2的分布取00,01,10,11的二元属性个数,列表,算比例.不对称的二元属性就忽略00的属性个数 序数:转换成排位rif,度量:r ...
- matlab生成滤波器系数组
用MATLAB生成的滤波器系数是可以控制增益的,一般归一化的目的是控制增益为1.滤波器的阶数由数据速率,过渡带宽.通带波纹和阴带波纹来决定, 在下图中FS,Apass,Astop固定之后,只要Fpas ...
- .net 导出Excel
CreateExcel(ExcelDs, ", f); void CreateExcel(DataSet ds, string typeid, string FileName) { Http ...
- 百度Web Uploader组件实现文件上传(一)
Web Uploader WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势 ...
- 2.2.9静态同步synchronized方法与synchronized(class)代码块
关键字synchronized还可以应用在static静态方法上,这样写那是对当前的*.java文件对应的class类进行持锁, 测试如下 package com.cky.bean; /** * Cr ...
- 1.2.2实现Runnable接口
使用Runnable创建线程 package com.cky.runner; /** * Created by chenkaiyang on 2017/12/2. */ public class My ...