6 μ's的影响力【数论 矩阵快速幂 费马小定理】【2020牛客寒假算法基础集训营1】

很多人看不到题目呀,那我拍一下。


实际上,这道题我们很容易推出它的矩阵快速幂形式。

其实就是x、y、\large a^{b}分别的幂了。

然后,就是维护对应的幂了,这时候,我们需要考虑特殊情况。

也就是在这里“\large 0^{0} = 0”这是一个很重要的性质!因为作为底数的0,实际上是被取模之后的0,而上面的作为指数的0,一定是不真正为0的,所以他们的幂次数一定是为0的!而我们正常的快速幂都是无法判断的,所以,最后我们需要加上一组特判!可以选择像我一样加在快速幂的函数内部。

当然,还有个细节就是我们处理矩阵快速幂的时候,取的模可是欧拉(mod),也就是mod - 1。这是费马小定理的原理。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const ll mod = 1e9 + 7LL, P = 1e9 + 6LL;
inline ll fast_mi(ll a, ll b, ll M)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1LL) ans = ans * a % M;
        a = a * a % M;
        b >>= 1LL;
    }
    if(!a) ans = 0; //这里特殊,因为存在0的0次幂,而第二个所谓的“0次幂”是假的0,其实是有真实值的
    return ans;
}
struct matrice
{
    ll a[3][3];
    matrice() { memset(a, 0, sizeof(a)); }
    friend matrice operator * (matrice x, matrice y)       //重载函数,矩阵的乘积得到的新矩阵
    {
        matrice ans;
        for(int i=0; i<2; i++)
        {
            for(int j=0; j<2; j++)
            {
                ll tmp = 0;
                for(int k=0; k<2; k++)
                {
                    tmp = (tmp + x.a[i][k] * y.a[k][j] % P) % P;       //最后得到的需要取mod
                }
                ans.a[i][j] = tmp;
            }
        }
        return ans;
    }
}Bas, AI, M1, M2, Bg, G;
matrice Fast_Mi(matrice x, ll ti)
{
    matrice ans;
    for(int i=0; i<3; i++) ans.a[i][i] = 1;  //构造单位阵
    while(ti)
    {
        if(ti & 1LL) ans = ans * x;
        x = x * x;
        ti >>= 1LL;
    }
    return ans;
}
ll N, x, y, a, b, K;
inline void init()
{
    Bas = matrice();
    Bas.a[0][0] = 1; Bas.a[0][1] = 1;
    Bas.a[1][0] = 1; Bas.a[1][1] = 0;
    AI = matrice();
    AI.a[0][0] = 1;
    AI.a[1][0] = 1;
}
int main()
{
    scanf("%lld%lld%lld%lld%lld", &N, &x, &y, &a, &b);
    a %= mod; x %= mod; y %= mod;
    b %= P;
    K = fast_mi(a, b, mod);
    if(N <= 3)
    {
        if(N == 1) printf("%lld\n", x % mod);
        else if(N == 2) printf("%lld\n", y % mod);
        else printf("%lld\n", x * y % mod * K % mod);
        return 0;
    }
    init();
    M1 = Fast_Mi(Bas, N - 3LL); M2 = Fast_Mi(Bas, N - 4LL);
    M1 = M1 * AI; M2 = M2 * AI;
    G = Fast_Mi(Bas, N - 1LL);
    printf("%lld\n", fast_mi(y, M1.a[0][0], mod) * fast_mi(x, M2.a[0][0], mod) % mod * fast_mi(a, b * (G.a[0][0] - 1LL + P) % P, mod) % mod);
    return 0;
}
/*
5 2 3 2 1
ans:1728
*/
发布了770 篇原创文章 · 获赞 927 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/104173399