hdu5667--Sequence

Holion August will eat every thing he has found. 

         Now there are many foods,but he does not want to eat all of them at once,so he find a sequence. 

fn=1,ab,abfcn1fn2,n=1n=2otherwise fn={1,n=1ab,n=2abfn−1cfn−2,otherwise 

         He gives you 5 numbers n,a,b,c,p,and he will eat  fn fn foods.But there are only p foods,so you should tell him  fn fn mod p.
Input
         The first line has a number,T,means testcase. 

         Each testcase has 5 numbers,including n,a,b,c,p in a line. 

    1T10,1n1018,1a,b,c109     1≤T≤10,1≤n≤1018,1≤a,b,c≤109, p p is a prime number,and  p109+7 p≤109+7.
Output
         Output one number for each case,which is  fn fn mod p.
Sample Input
1
5 3 3 3 233
Sample Output

190





( ab)p[n]= a* ((ab)p[n-1])c * ((ab)p[n-2]);递推式子可以这样写;
合并后变为(ab)p[n]=(ab)(c*p[n-1]+p[n-2]+1);
可以得到p[n]=c*p[n-1]+p[n-2]+1;

Fn=Fn-1*c+Fn-2+b;

然后我们也不难写出矩阵:


#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long  ll;
struct matrix
{
    ll a[3][3];
};
ll mod;
matrix A,B;
matrix mul(matrix aa,matrix bb)
{
    matrix res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0; i<3; i++)
    {
        for(int j=0; j<3; j++)
        {
            for(int k=0; k<3; k++)
            {
                res.a[i][j]=(res.a[i][j]+aa.a[i][k]*bb.a[k][j])%mod;
            }
        }
    }
    return res;
}
matrix pow(matrix aa,ll p)
{
    matrix res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0; i<3; i++)
        res.a[i][i]=1;
    while(p)
    {
        if(p&1)
            res=mul(res,aa);
        p>>=1;
        aa=mul(aa,aa);
    }
    return res;
}//矩阵快速幂
ll mod_pow(ll x,ll n,ll mod)
{
    ll res=1;
    while(n>0)
    {
        if(n&1)
            res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
int main()
{
    ll n,a,b,c,t;
    cin>>t;
    while(t--)
    {
        cin>>n>>a>>b>>c>>mod;
        A.a[0][0]=c;
        A.a[0][1]=1;
        A.a[0][2]=b;
        A.a[1][0]=1;
        A.a[1][1]=0;
        A.a[1][2]=0;
        A.a[2][0]=0;
        A.a[2][1]=0;
        A.a[2][2]=1;
        if(n==1)
            cout<<"1"<<endl;
        else if(n==2)
            cout<<mod_pow(a,b,mod);
        else
        {
            mod--;
            B =pow(A,(n - 2));
            ll tmp=B.a[0][0]*b+B.a[0][2];
            mod++;
            ll ans = mod_pow(a, tmp, mod);
            cout<<ans<<endl;
        }
    }
    return 0;
}
 
 
 
 
另一种方法:(同样AC)
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
typedef long long ll;
const int mod=1e9+7;
ll n,a,b,c,p;
struct matrix
{
    ll a[3][3];
};
matrix A;
void Iint(ll x)//矩阵初始化;
{
    A.a[0][0]=x;
    A.a[0][1]=1;
    A.a[0][2]=1;
    A.a[1][0]=1;
    A.a[1][1]=A.a[1][2]=0;
    A.a[2][0]=A.a[2][1]=0;
    A.a[2][2]=1;
}
matrix mul(matrix x,matrix y)//矩阵相乘
{
    matrix ans;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            ans.a[i][j]=0;
            for(int k=0;k<3;k++)
            {
                ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%(p-1);
                ans.a[i][j]%=(p-1);
            }
        }
    }
    return ans;
}
ll fast_fun(matrix temp,ll num)//矩阵快速幂;
{
    matrix s,base;
    for(int i=0;i<3;i++)//s初始化为单位矩阵
    {
        for(int j=0;j<3;j++)
        {
            s.a[i][j]=0;
            base.a[i][j]=temp.a[i][j];
        }
    }
    s.a[0][0]=s.a[1][1]=s.a[2][2]=1;
    while(num)
    {
        if(num&1)
        {
            s=mul(s,base);
        }
        base=mul(base,base);
        num=(num>>1);
    }
    return (s.a[0][0]+s.a[0][2])%(p-1);
}
ll fastpow(ll fx,ll fy)//快速幂求结果;
{
    ll s=1,base=fx;
    while(fy)
    {
        if(fy&1)
        {
            s*=base;
            s%=p;
        }
        base*=base;
        base%=p;
        fy=(fy>>1);
    }
    return s;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&p);
        Iint(c);
        if(n==1)printf("1\n");
        else if(n==2)printf("%lld\n",fastpow(a,b));
        else
        {
            if(a%p==0)printf("0\n");
            else {
            ll gg=fast_fun(A,n-2)*b%(p-1);
            printf("%lld\n",fastpow(a,gg));
            }
        }
    }
    return 0;
}

两种代码都能ac  但是有趣的是(3 2 2  2 2)两个代码的输出确不一样!!!试试吧。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值