zoukankan      html  css  js  c++  java
  • 数学-快速幂与矩阵快速幂

    1.A sequence of numbers

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3670

    题解:这是一道隐藏的快速幂的模板题,从数据我们就可以知道。对该题进行分析,如何判别是等差or等比,通过比较a[2]-a[1]==a[3]-a[2]如果相等,则为等差

    否则a[2]/a[1]==a[3]/a[2],就为等比,然后利用快速幂来解决等比。

    代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int mod=200907;
    ll N,K;
    ll a[10];
    
    ll fastPow(ll a,ll n)
    {
        ll res=1;
        while(n)
        {
            if(n&1)
                res=(res*a)%mod;
            a=(a*a)%mod;
            n>>=1;
        }
        return res;
    }
    
    int main()
    {
        ll i,j;
        cin>>N;
        while(N--)
        {
            for(i=1;i<=3;i++)
                cin>>a[i];
            cin>>K;
            if(a[2]-a[1]==a[3]-a[2])
            {
                cout<<(a[1]+((a[2]-a[1])%mod)*((K-1)%mod))%mod<<endl;
            }
            else if(a[2]/a[1]==a[3]/a[2])
            {
                ll q=a[2]/a[1];
                ll c=K-1;
                cout<<(fastPow(q,c)*a[1])%mod<<endl;
            }
        }
        return 0;
    }

    2.Rightmost Digit

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1061

    题解:这是一道典型的快速幂,只不过有一点需要注意,不要再完成运算后再取模,应该边运算边取模,否则会TLE

    代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    ll T;
    
    ll fastPow(ll a,ll n)
    {
        ll res=1;
        while(n)
        {
            if(n&1)
                res=(res*a)%10;
            a=(a*a)%10;
            n>>=1;
        }
        res=res%10;
        return res;
    }
    
    int main()
    {
        ll i,j,N;
        cin>>T;
        while(T--)
        {
            cin>>N;
            ll ans=fastPow(N,N);
            cout<<ans<<endl;
        }
        return 0;
    }

    3.矩阵快速幂

    题目:https://www.luogu.com.cn/problem/P3390

    题解:一道入门级矩阵快速幂的运算

    代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN=110;
    const int MOD=1e9+7;
    typedef long long ll;
    struct Matrix{
        ll m[MAXN][MAXN];
        Matrix()
        {
            memset(m,0,sizeof(m));
        }
    };
    Matrix Multi(Matrix a,Matrix b)
    {
        Matrix res;
        for(ll i=0;i<MAXN;i++)
        {
            for(ll j=0;j<MAXN;j++)
            {
                for(ll k=0;k<MAXN;k++)
                    res.m[i][j]=(res.m[i][j]+a.m[i][k]*b.m[k][j])%MOD;
            }
        }
        return res;
    }
    Matrix fastm(Matrix a,ll n)
    {
        Matrix res;
        for(ll i=0;i<MAXN;i++)
            res.m[i][i]=1;
        while(n)
        {
            if(n&1)
                res=Multi(res,a);
            a=Multi(a,a);
            n>>=1;
        }
        return res;
    }
    
    int main()
    {
        ll n,k,i,j;
        Matrix s;
        cin>>n>>k;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                cin>>s.m[i][j];
        }
        s=fastm(s,k);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                cout<<s.m[i][j]<<" ";
            cout<<endl;
        }
        return 0;
    }

    4.矩阵加速

    题目:https://www.luogu.com.cn/problem/P1939

    题解:一道需要求出对应矩阵的矩阵快速幂的运算。

    分析一下:

    a[n]=1*a[n-1]+0*a[n-2]+1*a[n-3]

    a[n-1]=1*a[n-1]+0*a[n-2]+0*a[n-3]

    a[n-2]=0*a[n-1]+1*a[n-2]+0*a[n-3]

    因此,我们可以总结出:

    进而,对其进行推到,因为我们已知a1=a2=a3=1,所以尽可能使右边的行列式替换成已知数,因此,最终的公式为:

     这样我们最终要求的就是an在数组中的位置为res.m[0][0],然后我们利用矩阵快速幂来求解行列式的n-3次方的值乘以行列式即可

    其中,需要注意的是MAXN=3还有对于小于等于3的进行特判,否则会TLE的

    代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int MAXN=3;
    const long long  MOD=1e9+7;
    struct Matrix
    {
        ll m[MAXN][MAXN];
        Matrix()
        {
            memset(m,0,sizeof(m));
        }
    };
    Matrix Multi(Matrix a,Matrix b)
    {
        Matrix res;
        for(ll i=0;i<MAXN;i++)
        {
            for(ll j=0;j<MAXN;j++)
            {
                for(ll k=0;k<MAXN;k++)
                    res.m[i][j]=(res.m[i][j]+a.m[i][k]%MOD*b.m[k][j]%MOD)%MOD;
                res.m[i][j]%=MOD;
            }
        }
        return res;
    }
    
    Matrix fastm(Matrix a,ll n)
    {
        Matrix res;
        for(ll i=0;i<MAXN;i++)
            res.m[i][i]=1;
        while(n)
        {
            if(n&1)
                res=Multi(res,a);
            a=Multi(a,a);
            n>>=1;
        }
        return res;
    }
    
    int main()
    {
        ll i,j,t,n;
        cin>>t;
        while(t--)
        {
            cin>>n;
            if(n <= 3) {
                printf("1
    ");
                continue;
            }
            Matrix k,s,res;
            k.m[0][0]=1;
            k.m[1][0]=1;
            k.m[2][0]=1;
    
            s.m[0][0]=1;s.m[0][1]=0;s.m[0][2]=1;
            s.m[1][0]=1;s.m[1][1]=0;s.m[1][2]=0;
            s.m[2][0]=0;s.m[2][1]=1;s.m[2][2]=0;
    
            s=fastm(s,n-3);
            res=Multi(s,k);
            cout<<res.m[0][0]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Apache Phoenix系列 | 从入门到精通(转载)
    Phoenix 简单介绍
    ES 调优查询亿级数据毫秒级返回!怎么做到的?--文件系统缓存
    Linux 文件系统缓存 -针对不同数据库有不同作用
    Hive 调优
    clickhouse 中文论坛
    从0到N建立高性价比的大数据平台(转载)
    ClickHouse 分布式高可用集群搭建(转载)
    Hive 模式设计
    Oracle 分区表中本地索引和全局索引的适用场景
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/13181045.html
Copyright © 2011-2022 走看看