hdu-5667 Sequence(矩阵快速幂+费马小定理+快速幂)

题目链接:

Sequence

Time Limit: 2000/1000 MS (Java/Others)   

 Memory Limit: 65536/65536 K (Java/Others)

Problem Description

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,abfcn−1fn−2,n=1n=2otherwise

He gives you 5 numbers n,a,b,c,p,and he will eat fn foods.But there are only p foods,so you should tell him 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.

1≤T≤10,1≤n≤10^18,1≤a,b,c≤10^9,p is a prime number,and p≤10^9+7.

Output

Output one number for each case,which is fn mod p.

Sample Input

1

5 3 3 3 233

Sample Output

190

题意:

问f(n)对p取模的结果;

思路:

(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;

这样的递推式可以用矩阵乘法得到第n项;这是矩阵乘法的一个应用,给matrix67大神的博客地址可以学习,点这里

构造矩阵乘法:

p[n]    c    1    1    p[n-1]

p[n-1]   =  1   0    0   *   p[n-2]

1       0   0    1      1

然后这中间还有一个问题,就是取模的问题;ab*p[n]%mod=ab*p[n]%(mod-1)%mod;

这是根据费马小定理得到的;a(p-1)Ξ1%p;这里给出地址

ab*p[n]%mod=ab*p[n]/(mod-1)*(mod-1)+b*p[n]%(mod-1)%mod;

令x=b*p[n]/(mod-1)则ab*p[n]%mod=ax*(mod-1)+b*p[n]%(mod-1)%mod=ab*p[n]%(mod-1)%mod;

这就是取模的结果啦;

然后就是快速幂算答案啦;

还有要注意的就是a%p==0的情况;

AC代码:

/*5667    0MS    1584K    1835B    G++    2014300227*/
#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;
}
时间: 2024-12-08 19:15:59

hdu-5667 Sequence(矩阵快速幂+费马小定理+快速幂)的相关文章

2014多校第一场 I 题 || HDU 4869 Turn the pokers(费马小定理+快速幂模)

题目链接 题意 : m张牌,可以翻n次,每次翻xi张牌,问最后能得到多少种形态. 思路 :0定义为反面,1定义为正面,(一开始都是反), 对于每次翻牌操作,我们定义两个边界lb,rb,代表每次中1最少时最少的个数,rb代表1最多时的个数.一张牌翻两次和两张牌翻一次 得到的奇偶性相同,所以结果中lb和最多的rb的奇偶性相同.如果找到了lb和rb,那么,介于这两个数之间且与这两个数奇偶性相同的数均可取到,然后在这个区间内求组合数相加(若lb=3,rb=7,则3,5,7这些情况都能取到,也就是说最后的

HDU 4549 M斐波那契数列 ( 矩阵快速幂 + 费马小定理 )

HDU 4549 M斐波那契数列 (  矩阵快速幂 + 费马小定理  ) 题意:中文题,不解释 分析:最好的分析就是先推一推前几项,看看有什么规律 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 100000

hdu 4704 Sum (费马小定理+快速幂)

//(2^n-1)%mod //费马小定理:a^n ≡ a^(n%(m-1)) * a^(m-1)≡ a^(n%(m-1)) (mod m) # include <stdio.h> # include <algorithm> # include <string.h> # define mod 1000000007 using namespace std; __int64 pow(__int64 n) { __int64 p=1,q=2; while(n) { if(n%

hdu 4704 费马小定理+快速幂

题意就是:做整数拆分,答案是2^(n-1) 由费马小定理可得:2^n % p = 2^[ n % (p-1) ]  % p 当n为超大数时,对其每个数位的数分开来加权计算 当n为整型类型时,用快速幂的方法求解 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; const in

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

hdu 4549 (矩阵快速幂+费马小定理)

题意:已知F0=a,F1=b,Fn=Fn-1*Fn-2,给你a,b,n求Fn%1000000007的值 思路:我们试着写几组数 F0=a F1=b F2=a*b F3=a*b2 F4=a2*b3 F5=a3*b5 我们发现a,b的系数其实是斐波那契数列,我们只需用矩阵快速幂求出相应系数就行,但是 这个系数随着增长会特别大,这时我们需要利用费马小定理进行降幂处理 费马小定理 ap-1≡1(mod p) 代码: #include <iostream> #include <cmath>

HDU 4549 M斐波那契数列(矩阵快速幂&amp;费马小定理)

ps:今天和战友聊到矩阵快速幂,想到前几天学长推荐去刷矩阵专题,挑了其中唯一一道中文题,没想到越过山却被河挡住去路... 题目链接:[kuangbin带你飞]专题十九 矩阵 R - M斐波那契数列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u 题意 Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2]

hdu 4549 M斐波拉契 (矩阵快速幂 + 费马小定理)

Problem DescriptionM斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input输入包含多组测试数据:每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 ) Output对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,

M斐波那契数列(矩阵快速幂+费马小定理)

M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1672    Accepted Submission(s): 482 Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a,