2020牛客寒假算法基础集训营1 J u's的影响力

2020牛客寒假算法基础集训营1

J u’s的影响力

2020牛客寒假算法基础集训营1 J u's的影响力_第1张图片
2020牛客寒假算法基础集训营1 J u's的影响力_第2张图片

题意

如题。

思路

我们可以发现,x和y的幂次是斐波那契数列的某一项,ab的幂次的递推公式为F[i] = F[i-1] + F[i-2] +1。所以我们可以用矩阵快速幂跑出幂次。但是由于幂次过大,无法直接求解,所以我们需要再套一个欧拉降幂,也就是幂次的递推时的模数为MOD-1。

坑点

要注意幂次模完之后可能会是0。

啊啊啊啊啊!卡了我一晚上!!!
当前时间:
当前时间

Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VII;
typedef vector<VII> VIII;
typedef pair<int, int> PII;

#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)

const ll MOD = 1e9 + 7;
const ll MODD = 1e9 + 6;

ll qpow(ll a, ll b, ll p)
{
    ll ret = 1;
    a %= p;
    while(b)
    {
        if(b&1) ret = ret*a%p;
        a = a*a%p;
        b >>= 1;
    }
    return ret;
}

struct Mat
{
    int row,col;
    ll a[5][5];
};

Mat mat_mul(Mat A,Mat B)
{
    Mat C;
    C.row=A.row;
    C.col=B.col;
    for(int i=1; i<=C.row; i++)
    {
        for(int j=1; j<=C.col; j++)
        {
            C.a[i][j]=0;
            for(int k=1; k<=A.col; k++)
                C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]%MODD)%MODD;
        }
    }
    return C;
}

///N为需要求第N项,A为初始矩阵(前几项),M为转移矩阵
Mat mat_quick_pow(ll N,Mat A,Mat M)
{
    Mat ans=A,B=M;
    while(N)
    {
        if(N&1) ans=mat_mul(B,ans);
        B=mat_mul(B,B);
        N >>= 1;
    }
    return ans;
}

int main()
{
    ll n, x, y, a, b;
    scanf("%lld%lld%lld%lld%lld", &n, &x, &y, &a, &b);
    a %= MOD;
    x %= MOD;
    y %= MOD;
    if(n == 1) printf("%lld\n", x);
    else if(n == 2) printf("%lld\n", y);
    else if(n == 3) printf("%lld\n", ((x*y)%MOD)*qpow(a, b, MOD)%MOD);
    else
    {
        Mat A,M;

        A.row=2;A.col=1;
        A.a[1][1]=1;A.a[2][1]=0;
        M.row=M.col=2;
        M.a[1][1]=1;M.a[1][2]=1;
        M.a[2][1]=1;M.a[2][2]=0;
        Mat ANS = mat_quick_pow(n-2, A, M);
        ll xx = ANS.a[2][1] + MODD;
        ll yy = ANS.a[1][1] + MODD;
        ll ans = qpow(x, xx, MOD)*qpow(y, yy, MOD)%MOD;

        A.row=3;A.col=1;
        A.a[1][1]=1;A.a[2][1]=0;A.a[3][1]=1;
        M.row=M.col=3;
        M.a[1][1]=1;M.a[1][2]=1;M.a[1][3]=1;
        M.a[2][1]=1;M.a[2][2]=0;M.a[2][3]=0;
        M.a[3][1]=0;M.a[3][2]=0;M.a[3][3]=1;
        ll bb = mat_quick_pow(n-3, A, M).a[1][1];
        ans = ans*qpow(qpow(a, b, MOD), bb, MOD)%MOD;

        printf("%lld\n", ans);
    }
    return 0;
}

你可能感兴趣的:(数论,牛客,寒假训练)