zoukankan      html  css  js  c++  java
  • 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;
    }
    



  • 相关阅读:
    Ueditor富文本编辑器
    ashx误删后,未能创建类型
    一个菜鸟的ASP.NET观光路线图
    地位尴尬的WebForm、ASP.NET核心知识(10)
    经典排序算法--归并排序
    经典排序算法--快速排序
    经典排序算法--冒泡排序
    经典排序算法--堆排序
    经典排序算法--简单选择排序
    经典排序算法--希尔排序
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672578.html
Copyright © 2011-2022 走看看