hdu 2256 Problem of Precision 构造整数 + 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=2256

题意:给定 n \left(1<=n<=10^9\right)   求解   \left\lfloor\left(\sqrt{2}+\sqrt{3}\right)^{2n}\right\rfloor\%1024

思路:\left(\sqrt{2}+\sqrt{3}\right)^{2}\right=5+2\sqrt{6} , 令  {x_n}+{y_n}\sqrt{6}=\left(\sqrt{2}+\sqrt{3}\right)^{n}\right

那么 x_n+y_n*\sqrt{6}=\left(x_{n-1}+y_{n-1}*\sqrt{6}\right)*\left(5+2\sqrt{6}\right)

得: x_n+y_n*\sqrt{6}=\left(5x_{n-1}+6y_{n-1}\right)+\left(x_{n-1}+5y_{n-1}\right)*\sqrt{6}

得转移矩阵: \begin{bmatrix}
x_n\\
y_n
\end{bmatrix}
=
\begin{bmatrix}
5&6\\
1&5
\end{bmatrix}
\begin{bmatrix}
x_{n-1}\\
y_{n-1}
\end{bmatrix}


但是上面求出来的并不是结果,并不是整数。需要加上\left(5-\sqrt{6}\right)^{n}, 由于\left(5-\sqrt{6}\right)^{n}<1

所以结果为2X_{n-1}-1

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define pb push_back
#define MK make_pair
#define A first
#define B second
#define clear0 (0xFFFFFFFE)
#define inf 0x3f3f3f3f
#define eps 1e-8
#define mod 1024
#define zero(x) (((x)>0?(x):-(x))<eps)
#define bitnum(a) __builtin_popcount(a)
#define lowbit(x) (x&(-x))
#define K(x) ((x)*(x))
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
template<typename T>
void read1(T &m)
{
    T x = 0,f = 1;char ch = getchar();
    while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
    while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
    m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
    if(a>9) out(a/10);
    putchar(a%10+'0');
}
inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; }
template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;}
template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}

struct Matrix{
    int row, col;
    int m[10][10];
    Matrix(int r,int c):row(r),col(c){ memset(m, 0, sizeof(m)); }

    bool unitMatrix(){
        if(row != col) return false;
        for(int i = 0;i < row;i++) //方阵才有单位矩阵;
                m[i][i] = 1;
        return true;
    }
    Matrix operator *(const Matrix& t){
        Matrix res(row, t.col);
        for(int i = 0; i < row; i++)
            for(int j = 0;j < t.col;j++)
                for(int k = 0; k < col; k++)
                    res.m[i][j] = (res.m[i][j] + m[i][k]*t.m[k][j])% mod;
        return res;
    }
    void print(){
        for(int i = 0;i < row; i++){
            for(int j = 0;j < col; j++)
                printf("%d ",m[i][j]);
            puts("");
        }
    }
};

Matrix pow(Matrix a, int n)
{
    Matrix res(a.row, a.col);
    res.unitMatrix();
    while(n){
        if(n & 1) res = res*a;
        a = a*a;
        n >>= 1;
    }
    return res;
}
int main()
{
    //freopen("data.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    Matrix mat(2,2);
    mat.m[0][0] = 5, mat.m[0][1] = 12;
    mat.m[1][0] = 2, mat.m[1][1] = 5;
    int T, kase = 1;
    scanf("%d",&T);
    while(T--){
        int n;
        read1(n);
        Matrix res = pow(mat, n-1);
        Matrix tmp(2,1);
        tmp.m[0][0] = 5, tmp.m[1][0] = 2;
        res = res*tmp;
        printf("%d\n", (2*res.m[0][0]-1)% mod);
    }
    return 0;
}

 

posted @ 2016-08-01 01:35  hxer  阅读(275)  评论(0编辑  收藏  举报