zoukankan      html  css  js  c++  java
  • 【题解】佳佳的斐波那契数列(矩阵)

    【题解】佳佳的斐波那契数列

    题目描述

    (Sigma i imes fib[i])的值

    数据范围

    (nle2^{31}-1)

    (Solution)

    看数据范围就会做的题...

    [设 \ f(n):=ib[n] \ g(n)=nf(n) \ s(n)=Sigma^{ile n}_{i=1}g(n) ]

    然后

    [f(i)=f(i-1)+f(i-2) \ s(i)=s(i-1)+g(i) ]

    不好求(g),但是可以直接这样

    [g(i)=i imes f(i)\ =i imes f(i-1)+i imes f(i-2) \ =(i-1)f(i-1)+(i-2)f(i-2)+f(i-1)+2f(i-2) \ =g(i-1)+g(i-2)+f(i-1)+2f(i-2) ]

    于是我们构造一个行向量(矩阵)

    [k=egin{pmatrix} \ g(i)&g(i+1)&f(i)&f(i+1)&s(i)&s(i+1) \ \ end{pmatrix} ]

    然后想办法构造一个转移矩阵

    [k imes egin{pmatrix}?end{pmatrix}=egin{pmatrix} \ g(i+1)&g(i+2)&f(i+1)&f(i+2)&s(i+1)&s(i+2) \ \ end{pmatrix} ]

    就直接根据转移式构造一下

    [egin{pmatrix}?end{pmatrix}= egin{pmatrix} 0&1&0&0&0&1 \ 1&1&0&0&0&1 \ 0&2&0&1&0&2 \ 0&1&1&1&0&1 \ 0&0&0&0&0&0 \ 0&0&0&0&1&1 end{pmatrix} ]

    初始矩阵是

    [egin{pmatrix} \ 1&2&1&1&1&3 \ \ end{pmatrix} ]

    最后直接取出第五列就好了((s(i)))

    #include<bits/stdc++.h>
    
    using namespace std;typedef long long ll;
    template < class ccf >
    inline ccf qr(ccf b){
        register char c=getchar();register int q=1;register ccf x=0;
        while(c<48||c>57)q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
        return q==-1?-x:x;}
    inline int qr(){return qr(1);}
    int mod,n;
    const int maxn=7;
    struct MTX{
        int data[maxn][maxn];
        MTX(){
    	for(register int t=1;t<=6;++t)
    	    for(register int i=1;i<=6;++i)
    		data[t][i]=0;
        }
        inline int* operator [](register int x){return data[x];}
        inline void unis(){
    	for(register int t=1;t<=6;++t)
    	    for(register int i=1;i<=6;++i)
    		data[t][i]=0;
    	for(register int t=1;t<=6;++t)
    	    data[t][t]=1;
        }
        
        inline void operator*=(MTX& f){
    	MTX ret;
    	for(register int k=1;k<=6;++k)
    	    for(register int t=1;t<=6;++t)
    		for(register int i=1;i<=6;++i)
    		    ret[t][i]=(0ll+ret[t][i]+1ll*data[t][k]*f[k][i]%mod)%mod;
    	*this=ret;
        }
        inline void operator ^=(const int&p){
    	MTX base=*this,ret;ret.unis();
    	for(register int t=p;t;base*=base,t>>=1)
    	    if(t&1) ret*=base;
    	*this=ret;
        }
    }yyb;
    ll vec[7]={0,1,2,1,1,1,3};
    
    int main(){
        freopen("fib.in","r",stdin);
        freopen("fib.out","w",stdout);
        n=qr();mod=qr();
        if(n<=2){
    	if(n< 1) printf("%d
    ",0);
    	if(n==1) printf("%d
    ",1%mod);
    	if(n==2) printf("%d
    ",3%mod);
    	return 0;
        }
        
        yyb[1][1]=0;yyb[1][2]=1;yyb[1][3]=0;yyb[1][4]=0;yyb[1][5]=0;yyb[1][6]=1;
        yyb[2][1]=1;yyb[2][2]=1;yyb[2][3]=0;yyb[2][4]=0;yyb[2][5]=0;yyb[2][6]=1;
        yyb[3][1]=0;yyb[3][2]=2;yyb[3][3]=0;yyb[3][4]=1;yyb[3][5]=0;yyb[3][6]=2;
        yyb[4][1]=0;yyb[4][2]=1;yyb[4][3]=1;yyb[4][4]=1;yyb[4][5]=0;yyb[4][6]=1;
        yyb[5][1]=0;yyb[5][2]=0;yyb[5][3]=0;yyb[5][4]=0;yyb[5][5]=0;yyb[5][6]=0;
        yyb[6][1]=0;yyb[6][2]=0;yyb[6][3]=0;yyb[6][4]=0;yyb[6][5]=1;yyb[6][6]=1;
        
        yyb^=n-1;
        
        ll ans=0;
        for(register int t=1;t<=6;++t)
    	ans=(ans+(vec[t]*yyb[t][5])%mod)%mod;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    java 16-8 泛型高级之通配符
    java 16 -7 泛型方法和泛型接口(泛型类相似)
    java 16-6 泛型
    java 16
    java 16 -4 LinkedList的特有功能
    java 16 -3 Vector的特有功能
    java 16-2 ArrayList的练习2
    java 16-1 ArrayList的练习1
    ll按时间排序和查看目录下文件数
    使用示例之线程调用自身
  • 原文地址:https://www.cnblogs.com/winlere/p/10805038.html
Copyright © 2011-2022 走看看