hdu5667 费马小定理加矩阵快速幂

题意很明显,给你公式问第n项,求一个loga构造一个新数列,

新数列可以用矩阵快速幂求。。

思考到这一步,发现还有问题,a的gn次方mod p怎么办?

考虑费马小定理,p是素数,所以当a不是p的倍数就成立,所以在gn中去掉k个p-1就好了,也就是在矩阵快速幂中对p-1取模,a是p的倍数的时候显然为0,

那么就可以愉快的搞了。。

贴代码0.0。。。数学很差一开始没想到费马小定理,又返回去看ppt。。。继续加油吧!

#include <iostream>
#include <vector>

using namespace std;

typedef vector<vector<long long> > mat;
typedef long long LL;

LL M = 1;
long long n,a,b,c;
mat mul(mat &A, mat &B)
{
    mat C(A.size(),vector<long long>(B[0].size()));

    for(int i = 0; i < A.size(); i++)
        for(int k = 0; k < B.size(); k++)
            for(int j = 0; j < B[0].size(); j++){
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) %(M-1);
            }
    return C;
}

mat pow(mat A, LL n)
{
    mat B(A.size(), vector<long long>(A.size()));
    for(int i = 0; i < A.size(); i++){
        B[i][i] = 1;
    }
    while(n>0){
        if(n & 1) B =mul(B,A);
        A = mul(A,A);
        n >>= 1;
    }
    return B;
}

LL Qpow(LL a,LL n)
{
    LL ans = 1;
    a=a%M;
    while(n)
    {
        if(n&1) ans = (ans*a)%M;
        a =(a*a)%M;
        n >>= 1;
    }
    return ans%M;
}


int main()
{
    int t;
    cin>>t;
    while(t--){
        cin>>n>>a>>b>>c>>M;
        if(a%M==0){
            if(n!=1)
            cout<<"0"<<endl;
            else cout<<"1"<<endl;
            continue;
        }
        vector<long long> v1;v1.push_back(1);v1.push_back(0);v1.push_back(0);
        vector<long long> v2;v2.push_back(1);v2.push_back(c);v2.push_back(1);
        vector<long long> v3;v3.push_back(0);v3.push_back(1);v3.push_back(0);
        mat C;
        C.push_back(v1);C.push_back(v2);C.push_back(v3);
        mat D;
        vector<long long> v4;v4.push_back(b);
        vector<long long> v5;v5.push_back(b);
        vector<long long> v6;v6.push_back(0);
        D.push_back(v4);D.push_back(v5);D.push_back(v6);
        C=pow(C,n-2);
        D=mul(C,D);
        cout<<Qpow(a,D[1][0])<<endl;
    }
    return 0;
}



原文地址:https://www.cnblogs.com/zhangxianlong/p/10672578.html