HDU 2256 Problem of Precision 解题报告(矩阵快速幂 + 构造)

Problem of Precision

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 844    Accepted Submission(s): 489


 

Problem Description

 

Input

The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n. (1 <= n <= 10^9)

 

Output

For each input case, you should output the answer in one line.

 

Sample Input

 

3 1 2 5

 

Sample Output

 

9 97 841



解题报告: 想了很久,没有思路….....…看了此篇解题报告

    推理过程如下:

构建矩阵:


|  Xn  |       |    5     12   |          |  Xn-1   |

|         |  =  |                   |    *    |             |

|  Yn  |       |    2      5    |          | Yn-1    |    


最终结果表明,中途取模也不会有影响,用矩阵快速幂求的xn即可。代码如下

/* ************
当看不懂代码时
动手敲敲会好得多
************ */
#include<iostream>
#include<cmath>
#include <cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int mod = 1024;

struct mat
{
    ll m[2][2];
    mat()
    {
        memset(m,0,sizeof(m));
    }
};
mat mul(mat &A,mat &B)
{
    mat C;
    for(int i=0;i<2;i++)
     {
         for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
                C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%mod;
     }
    return C;
}
mat pow(mat A,ll n)
{
    mat B;
    for(int i=0;i<2;i++) B.m[i][i]=1;
    while(n)
    {
        if(n&1) B=mul(B,A);
        A=mul(A,A);
        n >>=1;
    }
    return B;
}

int main()
{
    ///f(n) = 2*Xn - 0.101.. ^ n
    mat A;

    int L;
    A.m[0][0]=5;
    A.m[0][1]=12;
    A.m[1][0]=2;
    A.m[1][1]=5;

    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&L);
        mat B=pow(A,L-1);
        int res=2*(5*B.m[0][0]+2*B.m[0][1])-1;
        printf("%lld\n",res%mod);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42373330/article/details/81459080
今日推荐