码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-09-19 19:38:43      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

通道

题意:计算(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

 

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

标签:

原文地址:http://www.cnblogs.com/Rojo/p/4821983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!