HDU5667Sequence mathematical thinking + matrix fast power + fast power + Fermat's small theorem

This question just saw the circle.. I can't help but search the answers to the questions and find out.... emmmm...

Maybe I'm the only chicken...

Don't say anything. Please attach the blog Orz: https://blog.csdn.net/yuanjunlai141/article/details/51183053

There are two points in this problem: 1. Take logarithm and multiply to add.

2. Fermat's small theorem, when the matrix is fast power, mod should be reduced by 1. That is (a ^ g (n))% mod = a ^ g (n)% (MOD-1))% Mod

Then we find a magic point: when we finally find g(n), we can write it as g=b*res.a[0][0]+res.a[0][2], but write it as g=(b*res.a[0][0]+res.a[0][2])%MOD as WA. Why??? Is it because some places say we should pay attention to a%p==0??? Wow, it's really brain burning. QAQ

Attach AC Code:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long
#define pi acos(-1.0)

ll n,a,b,cc,MOD;
typedef struct
{
    ll a[3][3];
}mat;
mat c,res;

mat mul(mat x,mat y,ll n)
{
    mat cnt;
    memset(cnt.a,0,sizeof(cnt.a));
    for(ll i=0;i<n;i++)
        for(ll j=0;j<n;j++)
            for(ll k=0;k<n;k++)
                cnt.a[i][j]+=x.a[i][k]*y.a[k][j]%MOD;
    return cnt;
}
mat pow(ll k)
{
    c.a[0][0]=cc;c.a[0][1]=1;c.a[0][2]=b;
    c.a[1][0]=1;c.a[1][1]=0;c.a[1][2]=0;
    c.a[2][0]=0;c.a[2][1]=0;c.a[2][2]=1;
    memset(res.a,0,sizeof(res.a));
    for(ll i=0;i<3;i++)
        res.a[i][i]=1;
    while(k>0)
    {
        if(k&1)
            res=mul(res,c,3);
        c=mul(c,c,3);
        k=(k>>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;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cin>>n>>a>>b>>cc>>MOD;
        if(n==1)
        {
            printf("1\n");
            continue;
        }
        if(n==2)
        {
            cout<<QuickMod(a,b)%MOD<<endl;
            continue;
        }
        else
        {
            MOD--;//Fermat's theorem
            mat res=pow(n-2);//Attention is n-2 times!!!
            ll g=(b*res.a[0][0]+res.a[0][2]);
            MOD++;
            cout<<QuickMod(a,g)%MOD<<endl;
        }
    }
    return 0;
}

Now that matrix fast power is achieved, it is found that it is not the problem of getting results from recurrence, but how to get recurrence... This is the problem of mathematical thinking. It seems that we have to turn to the number theory question QAQ

Posted by scnjl on Fri, 03 Jan 2020 12:12:42 -0800