hdu 5667 Sequence 矩阵快速幂

题目链接:hdu 5667 Sequence

思路:因为fn均为a的幂,所以:

这样我们就可以利用快速幂来计算了

注意:

  1. 矩阵要定义为long long,不仅仅因为会爆,还会无限超时
  2. 要对a%p==0特判,以为可能出现指数%(p-1)==0的情况,那么在快速幂的时候返回的结果就是1而不是0了
/**************************************************************
    Problem:hdu 5667
    User: youmi
    Language: C++
    Result: Accepted
    Time:0MS
    Memory:1580K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
ll n,modp,modq;
const int maxn=3;
struct matrix
{
    ll mat[maxn][maxn];
    matrix operator*(const matrix & rhs)const
    {
        matrix ans;
        rep0(i,maxn)
            rep0(j,maxn)
            ans.mat[i][j]=0;
        rep0(i,maxn)
            rep0(j,maxn)
                rep0(k,maxn)
                ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*rhs.mat[k][j])%modp;
        return ans;
    }
    matrix operator^(ll k)const
    {
        matrix rhs=*this;
        matrix res;
        rep0(i,maxn)
            rep0(j,maxn)
                res.mat[i][j]=(i==j);
        while(k)
        {
            if(k&1)
                res=res*rhs;
            rhs=rhs*rhs;
            k>>=1;
        }
        return res;
    }
}x;
ll q_pow(ll a,ll b)
{
    ll res=1;
    while(b)//a%p==0,当b为0是返回的结果是1而不是0 !!!
    {
        if(b&1)
            res=res*a%modq;
        b>>=1;
        a=a*a%modq;
    }
    return res;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        ll a,b,c;
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&modq);
        modp=modq-1;
        if(n==1)
        {
            printf("1\n");
            continue;
        }
        else if(n==2)
        {
            printf("%I64d\n",q_pow(a,b));
            continue;
        }
        if(a%modq==0)
        {
            printf("0\n");
            continue;
        }
        x.mat[0][0]=c%modp,x.mat[0][1]=1,x.mat[0][2]=b%modp;
        x.mat[1][0]=1,x.mat[1][1]=0,x.mat[1][2]=0;
        x.mat[2][0]=0,x.mat[2][1]=0,x.mat[2][2]=1;
        x=x^(n-2);
        ll temp=((x.mat[0][0]*b)%modp+x.mat[0][2])%modp;
        temp=q_pow(a,temp);
        printf("%I64d\n",temp);
    }
}
时间: 2024-10-22 07:30:59

hdu 5667 Sequence 矩阵快速幂的相关文章

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

题意:不好复制,直接上链接http://acm.hdu.edu.cn/showproblem.php?pid=5667 思路: 观察递推式我们可以发现,所有的f_if?i??都是aa的幂次,所以我们可以对f_if?i??取一个以aa为底的loglog,即g_i=log_a\ f_ig?i??=log?a?? f?i?? 那么递推式变成g_i=b+c*g_{i-1}+g_{i-2}g?i??=b+c∗g?i−1??+g?i−2??,这个式子可以矩阵乘法 这题有一个小trick,注意a\ mod\

Uva10689 Yet another Number Sequence ( 矩阵快速幂 )

Uva 10689Yet another Number Sequence(  矩阵快速幂  ) 题意: 就是矩阵快速幂,没什么好说的. 分析: 其实还是斐波那契数列.只是最后对应的矩阵不是(1,1)是(a,b)了 MOD = 1; for( int i = 0; i < m; ++i ) MOD *= 10; 代码 #include <cstdio> #include <cstring> #include <algorithm> using namespace s

Hdu 4965(矩阵快速幂)

题目链接 Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 87    Accepted Submission(s): 39 Problem Description One day, Alice and Bob felt bored again, Bob knows Alice is a

HDU 5950 Recursive sequence 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5950 一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢? 矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n 其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就 会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系. i^4也一样,想要从i^4 递推到 (i

HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers

HDU 1005 Number Sequence 矩阵快速幂

Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 236241    Accepted Submission(s): 60070 Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A

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 fi

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n

HDU5950-Recursive sequence(矩阵快速幂)

题目链接:Recursive sequence 题意:给出n头母牛,第一头报a,第二头报b,第i头报f[i-2]*2+f[i-1]+i^4,问第n头母牛报数多少 分析:N,a,b<2^31,果断矩阵快速幂,关键是要推出公式,公式如下,仅作参考 1 0 0 0 0 0 0        1               1 1 1 0 0 0 0 0        i                i+1 1 2 1 0 0 0 0       i2              (i+1)2 1 3