• HDU6050: Funny Function(推公式+矩阵快速幂)


    传送门

    题意

    利用给出的式子求(F_{m,1})

    分析

    直接推公式(都是找规律大佬)
    (n为偶数,F_{m,1}=frac{2(2^n-1)^{m-1}}3)
    (n为奇数,F_{m,1}=F_{m-1,1}(2^n-1)-frac{2(4^{frac n2}-1)}3)
    抱歉啊,markdown矩阵相乘实在调不出来了,勉强看一看吧QAQ
    ( left[ egin{matrix} 2^n-1&-1 \ 0&1 end{matrix} ight] ag{3} )
    ( left[ egin{matrix} F_{m-1,1} \ frac{2(4^{frac n2}-1)}3 end{matrix} ight] ag{3} ) (=) ( left[ egin{matrix} F_{m,1}\ frac{2(4^{frac n2}-1)}3 end{matrix} ight] ag{3} )

    做一次矩阵快速幂即可

    trick

    m为1,n为偶数直接输出1

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    const int N = 2;
    const ll mod = 1e9+7;
    int t;
    ll n,m,n_2,n_4,ni_3;
    struct matrix
    {
        ll mp[N][N];
        matrix()
        {
            mem(mp,0);
        }
    };
    
    ll pow_mod(ll a,ll p)
    {
        ll ans=1;
        for(ll ret=a%mod;p;p>>=1,ret=ret*ret%mod) if(p&1) ans=ans*ret%mod;
        return ans;
    }
    matrix mul(matrix a,matrix b)//矩阵相乘
    {
        matrix ans;
        R(i,0,2)R(j,0,2)R(k,0,2) (ans.mp[i][j]+=a.mp[i][k]*b.mp[k][j]%mod)%=mod;
        return ans; 
    }
    matrix matrix_pow_mod(matrix a,ll p)
    {
        matrix ans,ret;
        R(i,0,2)R(j,0,2) ret.mp[i][j]=a.mp[i][j];
        ans.mp[0][0]=ans.mp[1][1]=1;
        while(p)
        {
            if(p&1) ans=mul(ans,ret);
            ret=mul(ret,ret);
            //R(i,0,2)R(j,0,2) printf("%I64d%c", ret.mp[i][j],j==1?'
    ':' ');
            p>>=1;
        }
        return ans;
    }
    void init()
    {
        n_2=(pow_mod(2LL,(ll)n)-1+mod)%mod;//求2^n-1
        n_4=(pow_mod(4LL,(ll)(n/2))-1+mod)%mod;//求4^n-1
        ni_3=pow_mod(3LL,mod-2);//求3的逆元
        n_4=n_4*2%mod*ni_3%mod;
    }
    
    void work1()
    {
        matrix temp,ret;
        temp.mp[0][0]=n_2,temp.mp[0][1]=-1;
        temp.mp[1][0]=0,temp.mp[1][1]=1;
        ret=matrix_pow_mod(temp,(ll)(m-1));//矩阵快速幂
        ll ans=0;
        //R(i,0,2)R(j,0,2) printf("%I64d
    ",ret.mp[i][j] );
        ans=(ret.mp[0][0]+ret.mp[0][1]*n_4%mod+mod)%mod;
        while(ans<0) ans+=mod;
        printf("%I64d
    ",ans );
    }
    
    void work2()
    {
        ll ans=pow_mod(n_2,(ll)(m-1));
        ans=ans*2%mod*ni_3%mod;
        ans=(ans+mod)%mod;
        printf("%I64d
    ",ans );
    }
    
    int main()
    {
        for(scanf("%d",&t);t--;)
        //F(i,1,10)F(j,1,10)
        {
            scanf("%lld %lld",&n,&m);
            //n=i,m=j;printf("n=%I64d m=%I64d
    ",n,m );
            init();
            if(m==1) { puts("1");continue; }
            if(n&1) work1();else work2();
        }
        return 0;
    }
    
  • 相关阅读:
    Vue3+Element-Plus-admin
    uniapp UI库推荐 uView官网/文档
    js 获取本月月初和月末时间操作
    el-dialog 无法弹出来
    Vue核心技术 Vue+Vue-Router+Vuex+SSR实战精讲
    sed 相关命令
    docker 启动 ubuntu
    vue 配置 history 模式
    typescript 相关
    fiddler 图片下载
  • 原文地址:https://www.cnblogs.com/chendl111/p/7272989.html
Copyright © 2020-2023  润新知