1. 程式人生 > >hdu 5667(矩陣快速冪)

hdu 5667(矩陣快速冪)

題意:給出一個遞推式求解fn的值。

分析:因為是遞推,很容易聯想到矩陣快速冪。但本題的式子是一個乘法,所以就採用求對數然後就變成加法了。當然本題求完對數後腰用費爾馬小定理來求解a的b次方,因為求對數,最後還要求回指數。本題求完對數的公式為f(n)=(b+f(n-1)*c+f(n-2))mod p-1;f1=0;f2=b;

最終結果為 a^(f(n))%p;

程式碼如下:

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;
struct Matrax{
    long long m[10][10];
}ter;
long long mod;
Matrax muli(Matrax a,Matrax b){
    Matrax p;
    for(int i=0;i<3;i++)
    for(int j=0;j<3;j++){
        p.m[i][j]=0;
        for(int k=0;k<3;k++){
            p.m[i][j]+=(a.m[i][k]*b.m[k][j])%(mod-1);
            p.m[i][j]%=mod-1;
        }
    }
    return p;
}//矩陣乘法
Matrax quick_mod(Matrax a,long long b){
    Matrax ans=ter;
    while(b){
        if(b&1){
            ans=muli(ans,a);
            b--;
        }
        else {
            b>>=1;
            a=muli(a,a);
        }
    }
    return ans;
}//快速冪
long long qmod(long long a,long long b){
    long long ans=1;
    while(b){
        if(b&1){
            ans=ans*a%mod;
            b--;
        }
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        long long n,a,b,c;
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&mod);
        if(n==1){
            puts("1");
            continue;
        }
        if(n==2){
            printf("%I64d\n",qmod(a,b));
            continue;
        }
        ter.m[0][0]=1;
        ter.m[0][1]=0;
        ter.m[0][2]=0;
        ter.m[1][0]=0;
        ter.m[1][1]=1;
        ter.m[1][2]=0;
        ter.m[2][0]=0;
        ter.m[2][1]=0;
        ter.m[2][2]=1;//初始化E矩陣   因為本題推出來是三元相加,所以用三維矩陣
        n-=2;
        Matrax A,B;
        A.m[0][0]=0;
        A.m[0][1]=1;
        A.m[0][2]=0;
        A.m[1][0]=1;
        A.m[1][1]=c;
        A.m[1][2]=0;
        A.m[2][0]=0;
        A.m[2][1]=b;
        A.m[2][2]=1;//這裡是中間連乘部分的矩陣
        A=quick_mod(A,n);
        B.m[0][0]=0;
        B.m[0][1]=b;
        B.m[0][2]=1;
        B.m[1][0]=0;
        B.m[1][1]=0;
        B.m[1][2]=0;
        B.m[2][0]=0;
        B.m[2][1]=0;
        B.m[2][2]=0;
        B=muli(B,A);//這裡是最初始的矩陣
//        cout<<B.m[0][1]<<endl;
//        cout<<a<<endl;
        printf("%I64d\n",qmod(a,B.m[0][1]+mod-1));
    }
    return 0;
}


相關推薦

hdu 5667(矩陣快速)

題意:給出一個遞推式求解fn的值。 分析:因為是遞推,很容易聯想到矩陣快速冪。但本題的式子是一個乘法,所以就採用求對數然後就變成加法了。當然本題求完對數後腰用費爾馬小定理來求解a的b次方,因為求對數,最後還要求回指數。本題求完對數的公式為f(n)=(b+f(n-1)*c+

HDU 2276 矩陣快速

test bottom tro little seconds sta struct 第一次 bold Kiki & Little Kiki 2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768

HDU - 2256 矩陣快速 帶根號的遞推

mat cpp matrix 有一個 rac 分析 eof rhs oid 題意:求$ [(\sqrt{2}+\sqrt{3})^{2n}] mod 1024 $ 分析: 把指數的2帶入 原式等於 $ [(5+2\sqrt{6})^n] $ 有一個重要的結論是n次運算後其結

HDU 6395 矩陣快速

矩陣很好構造: F:  f(n)                      A:   D           C            1                       B:   f(n-1)      f(n-1)                    

hdu 2276(矩陣快速)

題意:n個燈排成環,1的左邊是n,其他i號燈的左邊是i-1號,給定燈的初始狀態,每秒每個左邊的燈為1 的燈改變狀態。 影響第i個燈的狀態就是他左邊的燈和他本身,所以遞推式如下 (圖源百度) #include<iostream> #include<str

hdu 5015 (矩陣快速)

遞推公式:  (圖源網路) #include<iostream> #include<string> #include<cstdio> #include<cstring> #include<queue> #incl

hdu 1588 (矩陣快速)

F(g(i)) = F(b) + F(b+k)+F(b+2k)+....+F(b+nk)            = F(b) + (A^k)F(b) + (A^2k)F(b)+….+(A^nk)F(b)            = F(b) [ E +A^k + A^2k

233 Matrix hdu 5015 矩陣快速

Problem Description In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 … in th

HDU 6198 矩陣快速

ans=F(2*i+3)-1 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int m

矩陣快速演算法+例題(HDU 5667 Sequence)

矩陣快速冪是ACM比賽中對於求遞推式能用到的模板,能實現O(N^3*logM)的複雜度,其中 N是矩陣階乘,M是要求的第幾項。 對於矩陣快速冪,首先的得知道單位矩陣 ⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪11⋮110⋮0⋯⋯⋱⋯10⋮1⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ 明顯

hdu 5667 Sequence(矩陣快速+費馬小定理+快速)

#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #inc

HDU 5667 Sequence 矩陣快速 + 費馬小定理

olion August will eat every thing he has found.     Now there are many foods,but he does not want to eat all of them at once,so he find a

hdu 5667 Sequence【矩陣快速

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 285    Accepted Submis

HDU 5667 Sequence【矩陣快速+費馬小定理】

題目連結: 題意: Lcomyn 是個很厲害的選手,除了喜歡寫17kb+的程式碼題,偶爾還會寫數學題.他找到了一個數列: fn=1,ab,abfcn−1fn−2,n=1n=2otherwi

HDU 5667 Sequence (矩陣快速+費馬小定理)

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2687    Acce

HDU 5667 Sequence(矩陣快速

Problem Description Holion August will eat every thing he has found. Now there are many foods,b

HDU 5667 Sequence(矩陣快速+費馬小定理)

大意: He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him fn mod p. Inpu

hdu 5667 Sequence(矩陣快速)

Holion August will eat every thing he has found.Now there are many foods,but he does not want to eat all of them at once,so he find a sequence.fn=⎧⎩⎨⎪⎪1

hdu 4965 Fast Matrix Calculation(矩陣快速

觀察 while code 開始 mat col power tmp style 題意: 給你一個N*K的矩陣A和一個K*N的矩陣B,設矩陣C=AB,M=C^(N*N),矩陣Mmod6後,所有數的和是多少 思路: 剛開始我是直接計算的

hdu 1575 Tr A 矩陣快速

return mem include spa ret itl int color ons 水呀水呀水呀水 矩陣快速冪模板 #include<bits/stdc++.h> using namespace std; const int N = 12