• hdu 5451 Best Solver


    很显然这是矩阵快速幂的题

    但发现用矩阵快速幂,指数很大很大,没办法用欧拉降幂(傻乎乎的用欧拉降幂,欧拉降幂只是对底数为整数,做了3个小时),结果是由周期的,根据周期对指数进行降幂,然后再矩阵快速幂,最后答案减一,因为这是求的向上取整

    AC code:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 1e6 + 10;
    const int M = 2;
    
    typedef long long ll;
    
    int m=2;
    int MOD;
    struct Matrix{
        ll matrix[M][M];
    };
    void init(Matrix &res)
    {
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<m;j++)
                res.matrix[i][j]=0;
            res.matrix[i][i]=1;
        }
    }
    Matrix multiplicative(Matrix a,Matrix b)
    {
        Matrix res;
        memset(res.matrix,0,sizeof(res.matrix));
        for(int i = 0 ; i <m; i++)
            for(int j = 0 ; j < m ; j++)
                for(int k = 0 ; k < m; k++)
                    res.matrix[i][j] = (res.matrix[i][j]+a.matrix[i][k]%MOD*b.matrix[k][j]%MOD+MOD)%MOD;
        return res;
    }
    Matrix pow(Matrix mx,ll m)
    {
        Matrix res,base=mx;
        init(res); //初始为单位矩阵,即除主对角线都是1外,其他都是0
        while(m)
        {
            if(m&1)
                res=multiplicative(res,base);
            base=multiplicative(base,base);
            m>>=1;
        }
        return res;
    }
    
    
    ll fast_pow(ll a,ll n,ll mod)
    {
        ll ans = 1;
        while(n)
        {
            if(n&1) ans = ans * a % mod;
            a = a*a % mod;
            n >>= 1;
        }
        return ans;
    }
    ll ans[N];
    
    int looped[46337 + 10];
    
    int getloop(int mod)
    {
        if(looped[mod]) return looped[mod];
        ans[0] = 2%mod;ans[1] = 10%mod;
        for(int i = 2;;i++)
        {
            ans[i] = (ans[i - 1]*10ll%mod - ans[i - 2] + mod)%mod;
         //   cout<<i<<endl;
            if(ans[i-1] == ans[0] && ans[i] == ans[1])    return looped[mod] = i - 1;
    
        }
    
    }
    
    
    int main()
    {
        int t,kase = 0,x;
        memset(looped,0,sizeof(looped));
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&x,&MOD);
            int loop = getloop(MOD);
            //cout<<loop<<endl;
            int n = (fast_pow(2,x,loop) + 1 ) % loop;
            ll a = 5;
            ll b = 24;
            //cout<<n<<endl;
            if(n == 0)  printf("Case #%d: %lld
    ",++kase,1%MOD);
            else if(n == 1)  printf("Case #%d: %lld
    ",++kase,(2*a-1)%MOD);
            else{
                Matrix base={
                    2*a,-(a*a-b),
                    1,0
                };
                base=pow(base,n-1);
                printf("Case #%d: %lld
    ",++kase,(2*a%MOD*base.matrix[0][0]%MOD+2*base.matrix[0][1]%MOD+MOD - 1)%MOD);
            }
        }
    }
  • 相关阅读:
    单调队列和单调栈
    二叉搜索树(BST)
    高斯消元和高斯约旦消元 Gauss(-Jordan) Elimination
    扩展欧几里德算法
    基数排序
    智力题研究
    快速排序和快速选择
    快读模板
    C#知识点
    C#字段属性设置
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/9736345.html
Copyright © 2020-2023  润新知