【矩阵快速幂+循环节】HDU 5451 Best Solver

通道

题意:计算(5+26√)1+2^x.

思路:循环节是(p+1)*(p-1),然后就是裸的矩阵快速幂啦。

代码:

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

typedef long long ll;

const int N = 2;
int MOD;

struct Matrix{
    ll 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;
    }
};

ll Pow(Matrix &m , ll 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;
   // printf("%d\n", k);
    while(k){
        if(k&1)
            ans = ans*m;
        k >>= 1;
        m = m*m;
    }
   // out(ans);
    ll x = (ans.mat[0][0]*5+ans.mat[0][1]*2)%MOD;
    return (x * 2-1)%MOD;
}

ll NOW;

ll Pow(int x) {
    ll res = 1, two = 2;
    while (x > 0) {
        if (x & 1) res = (res * two) % NOW;
        two = (two * two) % NOW;
        x >>= 1;
    }
    return res;
}

int main(){
    int T;
    Matrix m;
    scanf("%d" , &T);
    int cas = 0;
    while(T-- > 0) {
        int n;
        scanf("%d%d" , &n, &MOD); 
        NOW = (MOD + 1) * (MOD - 1);
        ll nn = Pow(n) + 1 ;
        m.mat[0][0] = 5 ; m.mat[0][1] = 12;
        m.mat[1][0] = 2 ; m.mat[1][1] = 5;
        printf("Case #%d: %I64d\n" , ++cas, Pow(m , nn));
    }
}
View Code

 

posted @ 2015-09-19 18:36  mithrilhan  阅读(228)  评论(0编辑  收藏  举报