首页 > ACM题库 > HDU-杭电 > hdu 2256 Problem of Precision-快速幂-[解题报告]C++
2014
01-04

hdu 2256 Problem of Precision-快速幂-[解题报告]C++

Problem of Precision

问题描述 :

输入:

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)

输出:

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)

样例输入:

3
1
2
5

样例输出:

9
97
841

点击打开hdu 2256

思路: 矩阵快速幂

分析:

1 题目要求的是(sqrt(2)+sqrt(3))^2n %1024向下取整的值

 

 

3 这里很多人会直接认为结果等于(an+bn*sqrt(6))%1024,但是这种结果是错的,因为这边涉及到了double,必然会有误差,所以根double有关的取模都是错误的思路

代码:

/************************************************
 * By: chenguolin                               * 
 * Date: 2013-08-23                             *
 * Address: http://blog.csdn.net/chenguolinblog *
 ***********************************************/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MOD = 1024;
const int N = 2;

struct Matrix{
    int mat[N][N];
    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;
    }
};

int Pow(Matrix &m , int k){
    if(k == 1)
        return 9;
    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 >>= 1;
        m = m*m;
    }
    int x = (ans.mat[0][0]*5+ans.mat[0][1]*2)%MOD;
    return (2*x-1)%MOD;
}

int main(){
    int cas , n;
    Matrix m;
    scanf("%d" , &cas);
    while(cas--){
        scanf("%d" , &n); 
        m.mat[0][0] = 5 ; m.mat[1][1] = 5;
        m.mat[1][0] = 2 ; m.mat[0][1] = 12;
        printf("%d\n" , Pow(m , n));
    }
}

解题转自:http://blog.csdn.net/chenguolinblog/article/details/10212567


  1. 第23行:
    hash = -1是否应该改成hash[s ] = -1

    因为是要把从字符串s的start位到当前位在hash中重置

    修改提交后能accept,但是不修改居然也能accept