HDU3221 Brute-force Algorithm 矩阵快速幂+快速幂+费马小定理

这道题的解题过程和HDU5667很像。。

//附上炼接:https://blog.csdn.net/Cc_Sonia/article/details/81673677

我推出来f(n)=f(n-1)*f(n-2)后就不会了。。看了大佬们的博客,发现a,b的指数就是个斐波那契数列,,我我我…我怎么会这么菜555555…

附上大佬博客Orz:https://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html

还有就是,,我发现取模是个很玄学的东西。。。

有个公式很重要:A^B%P=A^( B%Phi[P] + Phi[P] )%P   (注:B>=Phi[P])

附上AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long

ll A,B,mod,MOD,n;
typedef struct
{
    ll a[2][2];
}mat;
mat c,res;

mat mul(mat x,mat y,int n)
{
    mat cnt;
    memset(cnt.a,0,sizeof(cnt.a));
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++)
                cnt.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
    return cnt;
}
mat pow(int n)
{
    c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
    c.a[1][1]=0;
    memset(res.a,0,sizeof(res.a));
    res.a[0][0]=res.a[1][1]=1;
    while(n>0)
    {
        if(n&1)
            res=mul(res,c,2);
        c=mul(c,c,2);
        n=(n>>1);
    }
    return res;
}
ll QuickMod(ll a,ll b)
{
    a=a%mod;
	ll ans=(ll)1;
    while(b)
    {
        if(b&1)
            ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans%mod;
}

ll eul(ll n)
{
    ll ans=n;
    for(ll i=2;i*i<=n;i++)
        if(n%i==0)
        {
            ans=ans/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    if(n>1)
        ans=ans/n*(n-1);
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int tt=1;tt<=t;tt++)
    {
        cin>>A>>B>>mod>>n;
        printf("Case #%d: ",tt);
        if(n==1)
        {
            cout<<A%mod<<endl;
            continue;
        }
        else if(n==2)
        {
            cout<<B%mod<<endl;
            continue;
        }
        else if(n==3)
        {
            cout<<A*B%mod<<endl;
            continue;
        }
        else if(mod==1)
        {
            printf("0\n");
            continue;
        }
        else
        {
            MOD=eul(mod);
            //cout<<"MOD="<<MOD<<endl;
            mat res=pow(n-2);
            ll index1=res.a[0][1];
            ll index2=res.a[0][0];
            if(index1>=MOD)
                index1=index1%MOD+MOD;
            if(index2>=MOD)
                index2=index2%MOD+MOD;
            ll ans1=QuickMod(A,index1);
            ll ans2=QuickMod(B,index2);
            cout<<ans1*ans2%mod<<endl;
        }
    }
    return 0;
}

 

点赞