P5303 [GXOI/GZOI2019]逼死强迫症(斐波拉契、矩阵乘法)
解析
非常妙的一個題,感受到了斐波拉契優(yōu)美的歸納性質(zhì)。
首先,不難發(fā)現(xiàn)只要兩個1*1的位置固定,中間的擺法就固定了,而兩邊的方案都是經(jīng)典的斐波拉契數(shù)列(設(shè)為 fif_ifi?)。
那么枚舉中間的間隔再枚舉左邊的長度,就有:
ans=2∑i=3n∑j=0n?ifjfn?i?jans=2\sum_{i=3}^n\sum_{j=0}^{n-i}f_jf_{n-i-j}ans=2i=3∑n?j=0∑n?i?fj?fn?i?j?
乘二是因為對于一種間隔,中間的磚有兩種擺法。
轉(zhuǎn)換一下求和順序:
ans=2∑i=0n?3fi∑j=0n?3?ifjans=2\sum_{i=0}^{n-3}f_i\sum_{j=0}^{n-3-i}f_jans=2i=0∑n?3?fi?j=0∑n?3?i?fj?
然后有一個斐波拉契的經(jīng)典結(jié)論(然而我并不會):
∑i=0nfi=fn+2?1\sum_{i=0}^nf_i=f_{n+2}-1i=0∑n?fi?=fn+2??1
證明直接歸納即可。
所以原式就等于:
2∑i=0n?3fi(fn?1?i?1)=2(∑i=0n?3fifn?1?i?(fn?1?1))=2(∑i=0n?1fifn?1?i+1?2fn?1?fn?2)2\sum_{i=0}^{n-3}f_i(f_{n-1-i}-1)=2(\sum_{i=0}^{n-3}f_if_{n-1-i}-(f_{n-1}-1))=2(\sum_{i=0}^{n-1}f_if_{n-1-i}+1-2f_{n-1}-f_{n-2})2i=0∑n?3?fi?(fn?1?i??1)=2(i=0∑n?3?fi?fn?1?i??(fn?1??1))=2(i=0∑n?1?fi?fn?1?i?+1?2fn?1??fn?2?)
設(shè) sn=∑i=0nfifn?is_n=\sum_{i=0}^nf_if_{n-i}sn?=∑i=0n?fi?fn?i?,答案就是 2(s(n?1)+1?2fn?1?fn?2)2(s(n-1)+1-2f_{n-1}-f_{n-2})2(s(n?1)+1?2fn?1??fn?2?)。
再看看 sns_nsn? 等于什么:
sn=∑i=0nfifn?i=fn+fn?1+∑i=0n?2fifn?is_n=\sum_{i=0}^nf_if_{n-i}=f_n+f_{n-1}+\sum_{i=0}^{n-2}f_if_{n-i}sn?=i=0∑n?fi?fn?i?=fn?+fn?1?+i=0∑n?2?fi?fn?i?
=fn+fn?1+∑i=0n?2fi(fn?i?1+fn?i?2)=fn+sn?1+sn?2=f_n+f_{n-1}+\sum_{i=0}^{n-2}f_i(f_{n-i-1}+f_{n-i-2})=f_n+s_{n-1}+s_{n-2}=fn?+fn?1?+i=0∑n?2?fi?(fn?i?1?+fn?i?2?)=fn?+sn?1?+sn?2?
(第二步可以拆 fn?if_{n-i}fn?i? 是因為此時有 n?i>=2n-i>=2n?i>=2)
這樣,我們就得到了 sss 的遞推式,也非常優(yōu)美。
把 f,sf,sf,s 拼在一起構(gòu)造出轉(zhuǎn)移矩陣,快速冪加速即可。
代碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") using namespace std;const int N=4e5+100; const int mod=1e9+7; inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } int n,m;struct matrix{int x,y;ll a[5][5];matrix(int X,int Y){x=X;y=Y;memset(a,0,sizeof(a));} }; matrix operator * (const matrix &u,const matrix &v){matrix res(u.x,v.y);for(int k=1;k<=u.y;k++){for(int i=1;i<=u.x;i++){ll tmp=u.a[i][k];for(int j=1;j<=v.y;j++){(res.a[i][j]+=tmp*v.a[k][j])%=mod;}}}return res; } int trans[5][5]={{},{0,0,1,0,1},{0,1,1,0,1},{0,0,0,0,1},{0,0,0,1,1}, }; matrix I(4,4),o(4,4),ori(1,4); matrix ksm(matrix x,int k){matrix res=I;while(k){if(k&1) res=res*x;x=x*x;k>>=1;}return res; }signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifint T=read();for(int i=1;i<=4;i++) I.a[i][i]=1;for(int i=1;i<=4;i++){for(int j=1;j<=4;j++) o.a[i][j]=trans[i][j];}ori.a[1][1]=1;ori.a[1][2]=1;ori.a[1][3]=1;ori.a[1][4]=2;while(T--){n=read();if(n<=1) puts("0");else{matrix res=ori*ksm(o,n-2);//printf("%lld %lld %lld %lld\n",res.a[1][1],res.a[1][2],res.a[1][3],res.a[1][4]);printf("%lld\n",(res.a[1][4]+1-(2*res.a[1][2]+res.a[1][1])%mod+mod)*2%mod);}}return 0; } /* 1 5 0 0 5.001 5.002 */總結(jié)
以上是生活随笔為你收集整理的P5303 [GXOI/GZOI2019]逼死强迫症(斐波拉契、矩阵乘法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P4849 寻找宝藏(模板:四维偏序)
- 下一篇: 现在笔记本电脑配置比较好的是什么配置(现