「BJOI 2019」勘破神机
传送门
problem
经过了一个月的艰苦尝试,你的研究团队破译了 “2”“2”“2” 型奥术宝石和 “3”“3”“3” 型奥术宝石的内部能量结构。
这两类结构有着一定的相似性,它们的内部具有 kkk 个反应核心,“2”“2”“2” 型奥术宝石的每个核心都可以看成是一个 2×n2×n2×n 的网格,而 “3”“3”“3” 型奥术宝石的每个核心都可以看成是一个 3×n3×n3×n 的网格。(注意奥术宝石的 kkk 和 nnn 可能不同)当神力反应进行时,每个核心自动填充满神力颗粒。
形式化地描述,每个神力颗粒可以看成是一个 1×21×21×2 横置或竖置的方格,核心填满的定义为每个网格都恰好被一某个方格覆盖。若在两种填满反应核心的方案中存在一个方格放置的位置或方式不同,就认为方案不同。
如填满 2×42×42×4 的网格有 555 种不同的方案,填满 3×23×23×2 的网格有 333 种不同的方案。
如果奥术宝石的 kkk 个核心的填充方式互不相同,它们就会组合出强大的咒术。黑袍想知道对于某个宝石一共有多少种不同的咒术(对于两种咒术组合,如果第一种咒术中每个核心 aaa 的填充方式都可以找到第二种咒术的某个核心 bbb,使得 aaa 和 bbb 的填充方式完全相同,则认为这两种咒术组合相同)。
对于宽度为 nnn 、反应核心个数为 kkk 的 “2”“2”“2” 型奥术宝石,设不同的咒术为 F(n,k)F(n,k)F(n,k) ;对于宽度为 nnn 、反应核心个数为 kkk 的 “3”“3”“3” 型奥术宝石,设不同的咒术为 G(n,k)G(n,k)G(n,k) 。
地灾军团的科技水平还不能精准测量反应核心的长度 nnn,只能确定出核心长度的大致范围 [l,r][l,r][l,r]。你需要计算出反应核心长度在此区间内的平均咒术数,即
ans2=1r−l+1∑n=lrF(n,k)ans_2=\frac1{r−l+1}\sum _{n=l}^rF(n,k)ans2=r−l+11n=l∑rF(n,k)
ans3=1r−l+1∑n=lrG(n,k)ans_3=\frac1{r−l+1}\sum _{n=l}^rG(n,k)ans3=r−l+11n=l∑rG(n,k)
数据范围:1≤l≤r≤10181≤l≤r≤10^{18}1≤l≤r≤1018,1≤k≤5011≤k≤5011≤k≤501。
solution
m=2m=2m=2 的情况
设 fif_ifi 表示斐波那契数列(f1=1,f2=1f_1=1,f_2=1f1=1,f2=1),那么用 1×21\times 21×2 的砖铺满 2×n2\times n2×n 的格子的方案数是 fn+1f_{n+1}fn+1(为了方便,我们一开始就令 l,rl,rl,r 加 111,这样答案就是 fnf_nfn),所以我们要求的实际上就是 ∑n=lr(fnk)\sum_{n=l}^r\binom{f_n}{k}∑n=lr(kfn)。
直接带有斐波那契的话好像不好做,我们考虑斐波那契数列的通项公式为:
fn=15(1+52)n−15(1−52)nf_n=\frac1{\sqrt5}\left(\frac{1+\sqrt5}{2}\right)^n-\frac1{\sqrt5}\left(\frac{1-\sqrt5}{2}\right)^nfn=51(21+5)n−51(21−5)n
那不妨设 A=15,B=−15,x=1+52,y=1−52A=\frac1{\sqrt5},B=-\frac1{\sqrt5},x=\frac{1+\sqrt5}{2},y=\frac{1-\sqrt5}{2}A=51,B=−51,x=21+5,y=21−5,那么 fn=Axn+Bynf_n=Ax^n+By^nfn=Axn+Byn。
这个先留着,待会用于把 fnf_nfn 拆开。
在学习第一类斯特林数时,我们貌似学习过这个公式:
xn‾=∑i=0n(−1)n−i[ni]xix^{\underline n}=\sum_{i=0}^n(-1)^{n-i}\begin{bmatrix}n\\i\end{bmatrix}x^ixn=i=0∑n(−1)n−i[ni]xi
其中 [ni]\begin{bmatrix}n \\i\end{bmatrix}[ni] 为第一类斯特林数。证明就在这里看啦。
又根据 (nm)=nm‾m!\binom n m=\frac{n^{\underline m}}{m!}(mn)=m!nm,我们继续化简:
∑n=lr(fnk)=1k!∑n=lr∑i=0k(−1)k−i[ki]fni=1k!∑n=lr∑i=0k(−1)k−i[ki](Axn+Byn)i=1k!∑n=lr∑i=0k(−1)k−i[ki]∑j=0i(ij)AjBi−j(xjyi−j)n=1k!∑i=0k(−1)k−i[ki]∑j=0i(ij)AjBi−j∑n=lr(xjyi−j)n\begin{aligned}\sum_{n=l}^r{f_n\choose k}&=\frac 1 {k!}\sum_{n=l}^r\sum_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}f_n^i\\&=\frac1{k!}\sum_{n=l}^r\sum_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}(Ax^n+By^n)^i\\&=\frac1{k!}\sum_{n=l}^r\sum_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum_{j=0}^i{i\choose j}A^jB^{i-j}(x^jy^{i-j})^n\\&=\frac1{k!}\sum_{i=0}^k(-1)^{k-i}\begin{bmatrix}k\\i\end{bmatrix}\sum_{j=0}^i{i\choose j}A^jB^{i-j}\sum_{n=l}^r(x^jy^{i-j})^n\\\end{aligned}n=l∑r(kfn)=k!1n=l∑ri=0∑k(−1)k−i[ki]fni=k!1n=l∑ri=0∑k(−1)k−i[ki](Axn+Byn)i=k!1n=l∑ri=0∑k(−1)k−i[ki]j=0∑i(ji)AjBi−j(xjyi−j)n=k!1i=0∑k(−1)k−i[ki]j=0∑i(ji)AjBi−jn=l∑r(xjyi−j)n
最后面的那个 ∑n=lr(xjyi−j)n\sum_{n=l}^r(x^jy^{i-j})^n∑n=lr(xjyi−j)n 是一个等比数列求和,要注意有公比 =1=1=1 的情况。
那我们就可以枚举 i,ji,ji,j 然后 O(k2logn)O(k^2\log n)O(k2logn) 算答案了。
还有一个细节是,就是 5\sqrt 55 在模 998244353998244353998244353 意义下是不存在的,那么我们类似于表示虚数的方法,把每个数表示成 a+b5a+b\sqrt 5a+b5 就可以了。
m=3m=3m=3 的情况
以下内容部分来自 ViXBob 的博客,实在不想写写不动了。
先考虑求出递推式,比较显然的是当 nnn 是奇数时答案是 000,所以设 gng_ngn 表示 3×2n3\times 2n3×2n 的答案。
如下图:
枚举一下第二种情况跨越红线的数量就有递推式:
gn=3×gn−1+2×∑i=1n−1gn−1−i=3×gn−1+2×∑i=0n−2gi\begin{aligned}g_n&=3\times g_{n-1}+2\times\sum_{i=1}^{n-1}g_{n-1-i}\\&=3 \times g_{n-1}+2\times\sum_{i=0}^{n-2}g_i\end{aligned}gn=3×gn−1+2×i=1∑n−1gn−1−i=3×gn−1+2×i=0∑n−2gi
则有:
{gn=3×gn−1+2×∑i=0n−2gign+1=3×gn+2×gn−1+2×∑i=0n−2gi\begin{cases}g_n=3 \times g_{n-1}+2\times\sum_{i=0}^{n-2}g_i\\g_{n+1}=3\times g_n+2\times g_{n-1}+2\times \sum_{i=0}^{n-2}g_i\end{cases}{gn=3×gn−1+2×∑i=0n−2gign+1=3×gn+2×gn−1+2×∑i=0n−2gi
差分一下:
gn+1=4×gn−gn−1g_{n+1}=4 \times g_n-g_{n-1}gn+1=4×gn−gn−1
也就是说 gng_ngn 的递推式为:
{gn=1,n=0gn=3,n=1gn=4×gn−1−gn−2,n>1\begin{cases}g_n=1,&n=0\\g_n=3,&n=1\\g_n=4 \times g_{n-1}-g_{n-2},&n>1\end{cases}⎩⎪⎨⎪⎧gn=1,gn=3,gn=4×gn−1−gn−2,n=0n=1n>1
用特征方程方程解得:
gn=3+36(2+3)n+3−36(2−3)ng_n=\frac{3+\sqrt3}{6}(2+\sqrt3)^n+\frac{3-\sqrt3}{6}(2-\sqrt3)^ngn=63+3(2+3)n+63−3(2−3)n
然后就是一模一样的求解方法了。
时间复杂度 O(k2logn)O(k^2\log n)O(k2logn)。
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=505,P=998244353,inv2=499122177,inv6=166374059;
int T,m,k,V,s[N][N],fac[N],ifac[N];
int add(int x,int y) {return x+y>=P?x+y-P:x+y;}
int dec(int x,int y) {return x-y< 0?x-y+P:x-y;}
int mul(int x,int y) {return 1ll*x*y%P;}
int power(int a,int b){int ans=1;for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a);return ans;
}
struct num{int x,y;num(int _x=0,int _y=0):x(_x),y(_y){}friend num operator+(const num &a,const num &b) {return num(add(a.x,b.x),add(a.y,b.y));}friend num operator-(const num &a,const num &b) {return num(dec(a.x,b.x),dec(a.y,b.y));}friend num operator-(const num &a,int b) {return num(dec(a.x,b),a.y);}friend num operator*(const num &a,int b) {return num(mul(a.x,b),mul(a.y,b));}friend num operator*(const num &a,const num &b){return num(add(mul(a.x,b.x),1ll*V*mul(a.y,b.y)%P),add(mul(a.x,b.y),mul(a.y,b.x)));}friend num Inv(const num &a){return num(a.x,P-a.y)*power(dec(mul(a.x,a.x),1ll*V*mul(a.y,a.y)%P),P-2);}friend num power(num a,ll b){num ans=num(1,0);for(;b;b>>=1,a=a*a) if(b&1) ans=ans*a;return ans;}
}A,B,X,Y;
void prework(){fac[0]=fac[1]=1;for(int i=2;i<N;++i) fac[i]=mul(fac[i-1],i);ifac[N-1]=power(fac[N-1],P-2);for(int i=N-2;~i;--i) ifac[i]=mul(ifac[i+1],i+1);s[0][0]=1;for(int i=1;i<N;++i)for(int j=1;j<N;++j)s[i][j]=add(s[i-1][j-1],mul(i-1,s[i-1][j]));
}
int C(int n,int m) {return n<m?0:mul(fac[n],mul(ifac[m],ifac[n-m]));}
void init(){if(m==2){V=5;X=num(inv2,inv2),Y=num(inv2,P-inv2),A=Inv(num(0,1)),B=Inv(num(0,P-1));}else{V=3;X=num(2,1),Y=num(2,P-1),A=num(inv2,inv6),B=num(inv2,P-inv6);}
}
ll l,r,L,R;
int solve(){int ans=0;for(int i=0;i<=k;++i){int res=0,tmp=((k-i)&1)?(P-s[k][i]):s[k][i];for(int j=0;j<=i;++j){num val1=power(A,j)*power(B,i-j)*C(i,j),val2=power(X,j)*power(Y,i-j);val2=(val2.x==1&&val2.y==0)?num((r-l+1)%P,0):(power(val2,r+1)-power(val2,l))*Inv(val2-1);res=add(res,(val1*val2).x);}ans=add(ans,mul(res,tmp));}return mul(mul(ans,ifac[k]),power((R-L+1)%P,P-2));
}
int main(){prework();scanf("%d%d",&T,&m),init();while(T--){scanf("%lld%lld%d",&L,&R,&k);(m==2)?(l=L+1,r=R+1):(l=(L+1)/2,r=R/2);printf("%d\n",solve());}return 0;
}
「BJOI 2019」勘破神机相关推荐
- 【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.用斯特林数把下降幂化为普通的幂次求和 ...
- 【luogu P5320】勘破神机(数学)(数列特征方程)(第一类斯特林数)
勘破神机 题目链接:luogu P5320 题目大意 给你 l,r,kl,r,kl,r,k(其中 l,rl,rl,r 很大,k≤501k\leq 501k≤501),求: 1r−l+1∑i=lrCfi ...
- [BJOI2019]勘破神机
[BJOI2019]勘破神机 推式子好题 m=2,斐波那契数列,$f_{n+1}$项 不妨$++l,++r$,直接求$f_n$ 求$\sum C(f_n,k)$,下降幂转化成阶乘幂,这样都是多项式了, ...
- [BJOI2019]勘破神机(斯特林数,数论)
[BJOI2019]勘破神机(斯特林数,数论) 题面 洛谷 题解 先考虑\(m=2\)的情况. 显然方案数就是\(f_i=f_{i-1}+f_{i-2}\),即斐波那契数,虽然这里求出来是斐波那契的第 ...
- 【BJOI2019】勘破神机【数论】
传送门(难得正经一回) 神题,思想值得学习. 首先明确题意: 两个子问题,一个2xN,一个3xN. 接下来对这个问题进行慢慢的推敲 解方案数 很明显,我们要先解决放置方案数的公式,才能做这个题. 对于 ...
- 「BJOI 2019」排兵布阵
传送门 problem 小 C 正在玩一款排兵布阵的游戏.在游戏中有 nnn 座城堡,每局对战由两名玩家来争夺这些城堡.每名玩家有 mmm 名士兵,可以向第 iii 座城堡派遣 aia_iai 名士 ...
- BJOI2019 勘破神机 新解
考场上就随便莽了个 Θ(k2logr)\Theta(k^2\log r)Θ(k2logr) 的做法发现反正能过,就不管了--直到最近又提起这道题. 事情的经过其实是这样的--偶然看到了 cz_xuy ...
最新文章
- python安装教程win8-python 2.7在win8.1上安装的方法
- Boost:形成const&到_1的测试程序
- 云服务器镜像麻烦吗_云服务器的镜像功能有什么作用?
- jquery的$.extend和$.fn.extend作用及区别(—)
- Redis在持久化时产生的延迟
- word List 21
- codeforces 122A-C语言解题报告
- windows传文件到linux服务器--- secureCRT PK xftp
- day9 集合基础命令
- Android 10 低内存应用白名单和应用保活
- 为什么电脑会突然蓝屏
- matlab 极限积分,实验二MATLAB中的极限和微分积分运算
- NS2学习---可视化Tcl生成工具NSG2
- 19 01 18 dango 模型
- 【Kafka】Kafka消费者相关策略
- 虚拟串口工具MCGS开发调试的灵活应用教程
- xiuno开发文档_$ip-XiunoPHP 4.0 开发手册
- 圆桌会回顾 | SecureBoost:挑战千万级别样本训练之性能提升篇
- 无线网调优案例分享,很实用
- NumPy(一.NumPy的介绍)