一本通1642【例 2】Fibonacci 第 n 项
1642: 【例 2】Fibonacci 第 n 项
sol:挺模板的吧,经典题吧qaq
(1)
1 0 * 1 1 = 1 1
1 0
(2)
1 1 * 1 1 = 2 1
1 0
(3)
2 1 * 1 1 = 3 2
1 0
所以第n项就是1 0 * (1,1)n
(1,0)
用快速幂优化就是矩阵快速幂了
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') /* 1 0 1 1 1 0 */ ll n,Mod; ll a[3][3],b[3][3],ans[3][3],c[3][3]; inline void Ad(ll &X,ll Y) { X=X+Y; X-=(X>=Mod)?Mod:0; return; } int main() { int i,j,k; n=read()-1; R(Mod); a[1][1]=a[1][2]=a[2][1]=1; a[2][2]=0; ans[1][1]=ans[2][2]=1; ans[1][2]=ans[2][1]=0; while(n) { if(n&1) { memset(c,0,sizeof c); for(i=1;i<=2;i++) { for(j=1;j<=2;j++) { for(k=1;k<=2;k++) Ad(c[i][j],ans[i][k]*a[k][j]%Mod); } } memmove(ans,c,sizeof ans); } memset(c,0,sizeof c); for(i=1;i<=2;i++) { for(j=1;j<=2;j++) { for(k=1;k<=2;k++) Ad(c[i][j],a[i][k]*a[k][j]%Mod); } } memmove(a,c,sizeof a); n>>=1; } b[1][1]=1; b[1][2]=0; memset(c,0,sizeof c); for(i=1;i<=1;i++) { for(j=1;j<=2;j++) { for(k=1;k<=2;k++) Ad(c[i][j],ans[i][k]*b[k][j]); } } memmove(b,c,sizeof b); Wl(b[1][1]); return 0; } /* input 5 1000 output 5 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!