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

来源:互联网 发布:昆山仕德伟网络 编辑:程序博客网 时间:2024/05/21 22:47

题意很明显,给你公式问第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;}


0 0
原创粉丝点击