HDU 2256 Problem of Precision(矩阵快速幂)

Posted lalalatianlalu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2256 Problem of Precision(矩阵快速幂)相关的知识,希望对你有一定的参考价值。

题目:就是求(sqrt(2)+sqrt(3))^(2*n)向下取整然后在MOD1024

思路:这个题挺有意思,但是这个题我觉得只能这样了,因为这个题可以做是因为这个题目限制的很死,我们把(sqrt(2)+sqrt(3))转化为(5+2*sqrt(6))^n

设Sn=An+bn,An=(5+2*sqrt(6))^n,Bn=(5-2*sqrt(6))^n,可以发现Bn是小于1的,那我们最后的答案就是Sn-1取模

然后我们构造Sn*((5+2*sqrt(6))+(5-2*sqrt(6))),继续化简就会得到Sn*10=Sn+1-Sn-1,然后矩阵快速幂就可以 了

代码:

#include <cstdio>
using namespace std;
typedef long long LL;

const int MOD=1024;
///使用前要先对r,c赋值
struct mat{
    long long a[30][30];
    int r,c;
    mat operator *(const mat &b)const{
        mat ret;
        for (int i=0;i<r;i++){
            for (int j=0;j<b.c;j++){
                ret.a[i][j]=0;
                for (int k=0;k<c;k++)
                    ret.a[i][j]+=a[i][k]*b.a[k][j],ret.a[i][j]%=MOD;
            }
        }
        ret.r=r;
        ret.c=b.c;
        return ret;
    }
    void init_unit(int x)
    {
        r=c=x;
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                if(i==j)a[i][j]=1;
                else a[i][j]=0;
            }
        }
    }
}unit;
mat qmod(mat p,LL n){
    unit.init_unit(p.c);
    mat ans=unit;
    while(n){
        if(n&1)ans=p*ans;
        p=p*p;
        n>>=1;
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        mat A;
        A.r=2;A.c=2;
        A.a[0][0]=10;A.a[0][1]=-1;
        A.a[1][0]=1;A.a[1][1]=0;
        mat B;
        B.r=B.c=2;
        B.a[0][0]=10;
        B.a[1][0]=2;
        mat ans;
        ans.r=ans.c=2;
        ans=qmod(A,n-1);
        ans=ans*B;
        printf("%lld
",(ans.a[0][0]+MOD-1)%MOD);
    }
    return 0;
}

 

以上是关于HDU 2256 Problem of Precision(矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

HDU2256-Problem of Precision(矩阵构造+高速幂)

hdu-2256 Problem of Precision---矩阵快速幂+数学技巧

HDU 2256 Problem of Precision 数论矩阵快速幂

HDU 2256 Problem of Precision(矩阵快速幂)

F - Problem of Precision

HDU2256&&HDU4565:给一个式子的求第n项的矩阵快速幂