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

题目要求求出(√2+√3)2n的整数部分再mod 1024。

(√2+√3)2n=(5+2√6)n

如果直接计算,用double存值,当n很大的时候,精度损失会变大,无法得到想要的结果。

我们发现(5+2√6)n+(5-2√6)n是一个整数(2√6的偶数次幂总会正负抵消掉),并且(5-2√6)n是小于1的。所以我们就只需要求出Sn-1即可。令

  An=(5+2√6)n;  Bn=(5-2√6)n.

  Sn=An+B    Sn为整数。

  Sn*((5+2√6)+(5-2√6))=Sn*10

  Sn*10=(5+2√6)n+1+(5-2√6)n+1+(5+2√6)n-1+(5-2√6)n-1

  Sn*10=Sn+1+Sn-1

  递推式:Sn=10*Sn-1-Sn-2

然后转化为矩阵快速幂求Sn

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int Mod=1024;
const int N=2;
struct Mat
{
    int mat[N][N];
}a;
Mat Multiply(Mat a, Mat b)
{
    Mat c;
    memset(c.mat, 0, sizeof(c.mat));
    for(int k = 0; k < 2; ++k)
        for(int i = 0; i < 2; ++i)
            if(a.mat[i][k])
                for(int j = 0; j < 2; ++j)
                    if(b.mat[k][j])
                        c.mat[i][j] = (c.mat[i][j] +a.mat[i][k] * b.mat[k][j])%Mod;
    return c;
}
Mat QuickPower(Mat a, int k)
{
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    for(int i = 0; i < 2; ++i)
        c.mat[i][i]=1;
    for(; k; k >>= 1)
    {
        if(k&1) c = Multiply(c,a);
        a = Multiply(a,a);
    }
    return c;
}
void InitMat(Mat &A)
{
    A.mat[0][0]=10; A.mat[0][1]=-1;
    A.mat[1][0]=1;  A.mat[1][1]=0;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        if(n==1)
            printf("9\n");
        else if(n==2)
            printf("97\n");
        else
        {
            InitMat(a);
            a=QuickPower(a,n-2);
            int ans=(a.mat[0][0]*98+a.mat[0][1]*10-1)%1024;  //我们求的是S[n]-1
            while(ans<0) ans+=1024;
            printf("%d\n",ans);
        }
    }
    return 0;
}
时间: 2024-10-10 21:01:00

HDU 2256 Problem of Precision 数论矩阵快速幂的相关文章

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

HDU 2256 Problem of Precision (矩阵快速幂) ACM 题目地址:HDU 2256 Problem of Precision 题意: 给出一个式子,求值. 分析: 推起来最后那步会比较难想. 具体过程见: 表示共轭只听说过复数的和图的... 这构题痕迹好明显... 跟基友开玩笑说:如果遇到这种题,推到Xn+Yn*sqrt(6)这步时,打表最多只能打到10就爆int了,这是输出正解和Xn,说不定眼神好能发现ans = Xn * 2 - 1呢.= =... 代码: /*

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

HDU 2256 题意: 计算?(2√+3√)2n?mod1024 思路: ∵f(n)=(2√+3√)2n=(5+26√)n=An+Bn?6√ ∴f(n?1)=An?1+Bn?1?6√ 又∵f(n)=(5+26√)?f(n?1) ∴f(n)=(5?An?1+12?Bn?1)+(2?An?1+5?Bn?1)?6√ 所以递推矩阵就是: (52125)?(An?1Bn?1)=(AnBn) A1=5,B1=2. 然后套矩阵快速幂模板即可求出An,Bn. 又∵(5+26√)n=An+Bn?6√ ∴(5?2

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))),继续化简就

HDU 5171 GTY&#39;s birthday gift 矩阵快速幂

点击打开链接 GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 225    Accepted Submission(s): 78 Problem Description FFZ's birthday is coming. GTY wants to give a gift to ZZF. He as

hdu 4965 Fast Matrix Calculation(矩阵快速幂)2014多校训练第9场

Fast Matrix Calculation                                                                   Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description One day, Alice and Bob felt bored again, Bob knows Ali

HDU 4965 Fast Matrix Calculation(矩阵快速幂)

HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次,可以变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个只有6x6,就可以用矩阵快速幂搞了 代码: #include <cstdio> #include <cstring> const int N = 1005; const int M = 10; int n, m; int A[N][M], B[M][N], C[M][M], CC[N]

HDU 3292 【佩尔方程求解 &amp;&amp; 矩阵快速幂】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=3292 No more tricks, Mr Nanguo Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 587    Accepted Submission(s): 400 Problem Description Now Sailormoon

hdu 4565 So Easy! (共轭构造+矩阵快速幂)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4565 题目大意: 给出a,b,n,m,求出的值, 解题思路: 因为题目中出现了开根号,和向上取整后求余,所以用矩阵快速幂加速求解过程的时候,会产生误差,就很自然地想到了凑数,因为(a-1)^2<b<a^2,得出0<a-sqrt(b)<1,则无论n取多大,(a-sqrt(b))^n都是小于1的,(a-sqrt(b))^n 与 (a+sqrt(b))^n共轭,两者展开后会相互抵销,所以(

hdu 4965 Fast Matrix Calculation(矩阵快速幂)

题意: 给你一个N*K的矩阵A和一个K*N的矩阵B,设矩阵C=AB,M=C^(N*N),矩阵Mmod6后,所有数的和是多少 思路: 刚开始我是直接计算的,开了一个1000*1000的矩阵,结果直接爆掉了 后来看了看题解,发现想的很巧妙 观察 M=ABABAB....AB,AB每次都是1000*1000,可是BA确是6*6的 那么 M=A(BABABA..BA)B,我们让BA进行矩阵快速幂就不会爆掉了 M=A(BA)^(N*N-1)B,最后计算一下就好了 代码: #include <iostrea