• 【题解】T54037 最开始


    传送门

    题目大意:

    对于(a+ frac 1{a^{}}=n)求$a^{m}+ frac 1{a^{m}} $,对(10^9+7)取模。

    题目做法:

    乍看此题,没有思路,但是如果用数学办法推导一下,就知道怎么做了。

    (f(x)=a^x+ frac 1{a^{x}})

    显然当((x>=y))时候(f(x+y)=f(x) imes f(y)-f(x-y))

    于是得到递推式:

    (f(x)=f(1) imes f(x-1)-f(x-2)),矩阵快速幂即可。

    关于这个逆元为什么不需要处理,是因为这个拆分的过程中,我们实际上没有进行无效的除法,我们得到的(f(x-y))访问的直接就是那个取模以后的值。

    上代码:

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<bitset>
    #include<ctime>
    
    using namespace std;
    
    
    #define TMP template < class ins >
    #define endl '
    '
    #define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;t++)
    #define ERP(t,a) for(register int t=head[(a)];t;t=e[t].nx)
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;t--)
    typedef long long ll;
    
    TMP inline ins qr(ins tag){
        char c=getchar();
        ins x=0;
        int q=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;
    }
    const ll mod=1e9+7;
    const int maxn=3;
    ll n;
    int K;
    struct mtx{
        ll data[maxn][maxn];
        mtx(){memset(data,0,sizeof data);}
        inline ll* operator [](int x){
    	return data[x];
        }
        inline void unis(){
    	RP(t,1,2)
    	    data[t][t]=1;
        }
        inline mtx operator *(mtx a){
    	mtx temp;
    	RP(t,1,2)
    	    RP(i,1,2)
    	    RP(k,1,2)
    	    temp[t][i]=((temp[t][i]+data[t][k]*a[k][i])%mod)%mod;
    	return temp;
        }
        inline mtx operator *=(mtx a){
    	return (*this)=(*this)*a;
        }
        inline mtx operator ^(int x){
    	mtx ans,base=(*this);
    	ans.unis();
    	while(x){
    	    if(x&1)
    		ans*=base;
    	    base*=base;
    	    x>>=1;
    	}
    	return ans;
        }
        inline mtx operator ^=(int x){
    	int p=x;
    	return (*this)=(*this)^p;
        }
        inline void print(){
    	RP(t,1,2){
    	    RP(i,1,2)
    		cout<<(data[t][i])%mod<<' ';
    	    cout<<endl;
    	}
    	cout<<endl;
        }
    };
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        n=qr(1ll);
        K=qr(1);
        mtx qaq;
        qaq[1][1]=n;
        qaq[1][2]=1;
        qaq[2][1]=-1;
        qaq[2][2]=0;
        qaq^=K-1;
        ll ans=((n*qaq[1][1])%mod+(2*qaq[2][1])%mod+mod)%mod;
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    CSS – rem, em, px
    CSS – Variables
    go等待子协程完成再结束
    go原生mysql链接
    [恢]hdu 2511
    linux中竖线'|',双竖线‘||’,&和&&的意思
    SSH隧道:端口转发功能详解
    shell脚本执行返回的状态码
    第1章 ssh命令和SSH服务详解
    shell脚本中各种括号的区别以及用法
  • 原文地址:https://www.cnblogs.com/winlere/p/10307980.html
Copyright © 2020-2023  润新知