【矩阵快速幂+循环节】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));
    }
}

时间: 2024-10-13 19:34:19

【矩阵快速幂+循环节】HDU 5451 Best Solver的相关文章

hdu 4291(矩阵快速幂 + 循环节)

题意:求s s = g(g(g(n))) mod 1000000007 其中g(n) g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0 题解:普通的矩阵快速幂会超时,看到别人的题解是需要计算循环节得到小的MOD从而减小计算量.1000000007太大,需要计算更小的一个循环节,新技能get. #include <stdio.h> #include <string.h> struct Mat { long long g[3][3]; }ori

HDU——4291A Short problem(矩阵快速幂+循环节)

A Short problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2461    Accepted Submission(s): 864 Problem Description According to a research, VIM users tend to have shorter fingers, compared

[矩阵快速幂+循环节]hdu4291

题意: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0 分析: 这个递推关系可以用矩阵快速幂来解决,但是这个题的问题是mod很大,会爆long long 并且超时的.那么这就需要一些特技了. 于是看到大家都用的循环节,但是网上对为什么要这么取循环节却都模糊或者答非所问,大概都不太晓得,知道可以A提就可

HDU 4291 A Short problem(矩阵快速幂+循环节)

题目链接": http://acm.hdu.edu.cn/showproblem.php?pid=4291 题意: g(0)=0,g(1)=1; g(n) = 3g(n - 1) + g(n - 2): 求g(g(g(n))) mod 109 + 7 分析: 首先我们得认识到,如果一层一层算是必定会超时的. 其次,取模运算是有循环节的. step1我们找出g(x)%1000000007的循环节 mod1 step2 设g(g(n)) = g(x) x=g(n) 对mod1 取模得到mod2. 剩

acdream 1060 递推数 (矩阵快速幂+循环节)

链接:click here~~ 题意: 递推数 Problem Description 已知A(0) = 0 , A(1) = 1 , A(n) = 3 * A(n-1) + A(n-2) (n ≥ 2)    求 A(A(A(A(N)))) Mod (1e9 + 7) Input 第一行一个整数 T (T ≤ 10000) 代表数据组数 每组数据占一行,一个整数 n (1 ≤ n ≤ 1e12) Output 对于每组测试数据输出一个整数. Sample Input 4 1 23574 278

hdu 5451 Best Solver(矩阵快速幂+循环节)

题意: 已知,给你整数x,和一个素数M,求[y]%M 思路: 设 (5+2√6)n=Xn+Yn*√6 Xn+Yn*√6 =(Xn-1+Yn-1*√6)*(5+2√6) => 5*Xn-1 + 12*Yn-1 + (2*Xn-1 + 5*Yn-1 )*√6 Xn =  5*Xn-1 + 12*Yn-1: Yn =  2*Xn-1 + 5*Yn-1: 然而√6还是一个大问题,解决办法: (5 - 2√6)n = Xn - Yn*√6 (5+2√6)n=Xn+Yn*√6 + Xn - Yn*√6 -

HDU 4291 A Short problem (2012成都网络赛,矩阵快速幂+循环节)

链接: click here~~ 题意: According to a research, VIM users tend to have shorter fingers, compared with Emacs users. Hence they prefer problems short, too. Here is a short one: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where

矩阵快速幂AC代码HDU 2035

#include <iostream> using namespace std;const int MOD = 1000;//像这样的一个常量就应该专门定义一下 int PowMod(int a, int n)//a^n%MOD { int ret = 1; while(n) { if(n & 1) ret = ret * a % MOD; //变为二进制,然后就可以专门进行分解计算,十分的方便,要求是结合位运算一同使用 a = a * a % MOD; //这里要求特别的注意,因为是

一些特殊的矩阵快速幂 hdu5950 hdu3369 hdu 3483

思想启发来自, 罗博士的根据递推公式构造系数矩阵用于快速幂 对于矩阵乘法和矩阵快速幂就不多重复了,网上很多博客都有讲解.主要来学习一下系数矩阵的构造 一开始,最一般的矩阵快速幂,要斐波那契数列Fn=Fn-1+Fn-2的第n项,想必都知道可以构造矩阵来转移 其中,前面那个矩阵就叫做系数矩阵(我比较喜欢叫转移矩阵) POJ3070 Fibonacci 可以试一试 1 #include<cstdio> 2 typedef long long ll; 3 const ll md=10000; 4 st