J:u's的影响力(矩阵快速幂)

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

传送门

题意:

在这里插入图片描述

思路:

写几项,推导x,y,a^b的系数即可,然后找好和项数对应的关系
x,y都是斐波那契的某一项,然后正常看的话,a^b的系数应该是前两项之和加1,仔细观察发现,它的系数也是斐波那契的某一项减1即可
用矩阵快速幂算系数,因为数据大,然后还有就是用欧拉降幂欧拉降幂传送门
1e9+7是素数,它的欧拉函数值是1e9+6
我的推导过程
在这里插入图片描述

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int phi=1e9+6;
ll quick(ll a,ll b){//快速幂
    ll ans=1;
    while(b){
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b/=2;
    }
    return ans%mod;
}


struct sa
{
    ll m[2][2];
};
sa Mul(sa a,sa b)//矩阵乘法
{
    sa c;
    memset(c.m,0, sizeof(c.m));
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
                c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%phi)%phi;
    return c;
}

sa quickjz(sa a,ll n)//矩阵快速幂
{
    sa res;
    memset(res.m,0, sizeof(res.m));
    res.m[0][0]=1;
    res.m[1][1]=1;
    while(n)
    {
        if(n&1)
            res=Mul(res,a);
        n/=2;
        a=Mul(a,a);
    }
    return res;
}
int main()
{
    ll n,x,y,a,b;
    scanf("%lld%lld%lld%lld%lld",&n,&x,&y,&a,&b);
    if(n==1){
        printf("%lld\n",x%mod);
        return 0;
    }
    if(n==2){
        printf("%lld\n",y%mod);
        return 0;
    }
    x%=mod;
    y%=mod;
    a%=mod;
    if(a==0||x==0||y==0){//需要特判
        printf("0\n");
        return 0;
    }
    sa k={1,1,1,0},q={1,1,1,0},l={1,1,1,0};
    k=quickjz(k,n-3);
    ll p1=(k.m[1][0]+k.m[1][1])%phi;//x的系数
    q=quickjz(q,n-2);
    ll p2=(q.m[1][0]+q.m[1][1])%phi;//y的系数
    l = quickjz(l, n - 1);
    ll p3=(l.m[1][0]+l.m[1][1]-1);//a^b的系数
    a=quick(a,b);
    ll ans=1;
    ans=quick(x,p1)*quick(y,p2)%mod*quick(a,p3)%mod;
    printf("%lld\n",ans);
    return 0;
}
发布了142 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44091178/article/details/104184501