zoukankan      html  css  js  c++  java
  • HDU2256&&HDU4565:给一个式子的求第n项的矩阵快速幂

    HDU2256

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2256

    题意:求(sqrt(2)+sqrt(3))^2n%1024是多少。

    这个题算是hdu4565的一个常数版本了,所以我们先说这道题。对于这道题的做法我们可以计算((sqrt(2)+sqrt(3))^2)^n=(5+2*sqrt(6))^n,对于(5+2*sqrt(6))^n我们知道答案必定是以an+bn*sqrt(6),而对于下一项我们只需要求(an+bn*sqrt(6))*(5+2*sqrt(6))=5*an+12*bn+2*an*sqrt(6)+5*bn*sqrt(6),所以a(n+1)=5*an+12*bn; b(n+1)=2*an+5*bn。有了这个递推式我们就可以构造矩阵求an,bn。

    这里还有一点对于(5+2*sqrt(6))^n=an+bn*sqrt(6); 同理(5-2*sqrt(6))^n=an-bn*sqrt(6);两式相加(5+2*sqrt(6))^n+(5-2*sqrt(6))^n=2*an,当n趋于无穷的时候lim(5-2*sqrt(6))^n=0,因为5-2*sqrt(6)<1。

    所以我们可以得到答案(5+2*sqrt(6))^n约等于2*an,且实际值是比2*an要小的且小于2*an-1要大的,所以由题目的意思我们向下取整,ans=2*an-1;具体看代码,其他都是矩阵快速幂的模板。

    //Author: xiaowuga
    #include <bits/stdc++.h>
    #define maxx INT_MAX
    #define minn INT_MIN
    #define inf 0x3f3f3f3f
    #define n 2
    #define MOD 1024
    using namespace std;
    typedef long long ll;
    struct Matrix{
        ll mat[4][4];
        Matrix operator * (const Matrix & m) const{
            Matrix tmp;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++){
                    tmp.mat[i][j]=0;
                    for(int k=0;k<n;k++){
                        tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                        tmp.mat[i][j]%=MOD;
                    }
                }
            return tmp;
        }
    };
    Matrix POW(Matrix &m,int k){
        Matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for(int i=0;i<n;i++) ans.mat[i][i]=1;
        while(k){
            if(k&1) ans=ans*m;
            k/=2;
            m=m*m;
        }
        return ans;
    }
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        ll T,num;
        cin>>T;
        while(T--){
            cin>>num;
            Matrix m;
            m.mat[0][0]=5; m.mat[0][1]=12; m.mat[1][0]=2; m.mat[1][1]=5;
            Matrix ans=POW(m,num-1);
            ll sum=0,f[2]={5,2};
            for(int i=0;i<2;i++)
                sum+=ans.mat[0][i]*f[i]%MOD;
            sum%=MOD;
            ll x=(2*sum-1)%MOD;
            cout<<x<<endl;
        }
        return 0;
    }

    HDU4565

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565

    题意:算是上面那道题的一个升级版本啦。现在是a和b不是固定的的常数了。和上面的做法一样。注意题目中给出a-sqrt(b)<1的条件,所以基本和上道题是一样的了,类比一下吧!很简单的。但是这里是向上取整,所以答案是2*an。具体看代码吧。由于上面那道题在常数情况下已经说得很明白了。这道题就不说了

    //Author: xiaowuga
    #include <bits/stdc++.h>
    #define maxx INT_MAX
    #define minn INT_MIN
    #define inf 0x3f3f3f3f
    #define size 2
    int MOD;
    using namespace std;
    typedef long long ll;
    struct Matrix{
        ll mat[4][4];
        void clear(){
            memset(mat,0,sizeof(mat));
        }
        Matrix operator * (const Matrix & m) const{
            Matrix tmp;
            for(int i=0;i<size;i++)
                for(int j=0;j<size;j++){
                    tmp.mat[i][j]=0;
                    for(int k=0;k<size;k++){
                        tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                        tmp.mat[i][j]%=MOD;
                    }
                }
            return tmp;
        }
    };
    Matrix POW(Matrix &m,int k){
        Matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for(int i=0;i<size;i++) ans.mat[i][i]=1;
        while(k){
            if(k&1) ans=ans*m;
            k/=2;
            m=m*m;
        }
        return ans;
    }
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        ll  a,b,n;
        while(cin>>a>>b>>n>>MOD){
            Matrix m;
            m.clear();
            m.mat[0][0]=m.mat[1][1]=a%MOD;
            m.mat[0][1]=b%MOD;m.mat[1][0]=1;
            Matrix ans=POW(m,n-1);
            ll sum=(ans.mat[0][0]*a%MOD+ans.mat[0][1]%MOD)%MOD;
            cout<<2*sum%MOD<<endl;
        }
        return 0;
    }
  • 相关阅读:
    客户端无法获取IP
    两种添加数据到WEB DropDownList 控件的方法
    DataReader的使用方法
    标准SQL的update语句三种用法
    标准SQL的update语句三种用法
    DataReader的使用方法
    DataReader的使用方法
    标准SQL的update语句三种用法
    DataReader的使用方法
    标准SQL的update语句三种用法
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7213707.html
Copyright © 2011-2022 走看看