hdu4565So Easy!+矩阵快速幂+广义斐波拉契

原创 2016年08月31日 11:02:45

Problem Description
  A sequence Sn is defined as:
这里写图片描述
Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
  You, a top coder, say: So easy!

Input
  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231.The input will finish with the end of file.

Output
  For each the case, output an integer Sn.

Sample Input

2 3 1 2013
2 3 2 2013
2 2 1 2013

Sample Output

4
14
4

Source
2013 ACM-ICPC长沙赛区全国邀请赛——题目重现

直接递推构造矩阵,然后快速幂。参考上一篇博客:http://blog.csdn.net/xtulollipop/article/details/52382791
(a1)2<b<a2所以依然可以(a+b)n(ab)n相加。
向上取整就是向下取整+1,所以有答案2*An-1+1=2*An

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define pi acos(-1.0)
#define EPS 1e-6    //log(x)
#define e exp(1.0); //2.718281828
//#define mod 1000000007
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#pragma comment(linker,"/STACK:102400000,102400000")
typedef long long LL;

#define debug(x) cout<<x<<endl;
#define debug2(x) cout<<x<<" ";

//#define MOD 10000007
LL MOD;
struct Mat{
    int n,m;
    LL mat[9][9];
};
Mat operator *(Mat a,Mat b){
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    c.n = a.n,c.m = b.m;

    for(int i=1;i<=a.n;i++){
        for(int j=1;j<=b.m;j++){
            for(int k=1;k<=a.m;k++){
                c.mat[i][j] += (a.mat[i][k]*b.mat[k][j])%MOD;
                c.mat[i][j] %= MOD;
            }
        }
    }
    return c;
}
Mat operator +(Mat a,Mat b){
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    c.n = a.n,c.m = a.m;

    for(int i=1;i<=a.n;i++){
        for(int j=1;j<=a.m;j++){
            c.mat[i][j] = (a.mat[i][j]+b.mat[i][j])%MOD;
        }
    }
    return c;
}
Mat operator ^(Mat a,LL k){
    Mat c;
    memset(c.mat,0,sizeof(c.mat));
    c.n = a.n,c.m = a.n;
    for(int i=1;i<=a.n;i++)c.mat[i][i] = 1;

    while(k){
        if(k&1){
            c = c*a;
        }
        a = a*a;
        k>>=1;
    }
    return c;
}
void out(Mat a){
    for(int i=1;i<=a.n;i++){
        for(int j=1;j<=a.m;j++){
            printf(j==a.m? "%I64d\n":"%I64d ",a.mat[i][j]);
        }
    }
}
LL quickPow(LL x, LL n, LL mm)
{
    LL a = 1;
    while (n)
    {
        a *= n&1 ? x : 1;
        a %= mm;
        n >>= 1 ;
        x *= x;
        x %= mm;
    }
    return a;
}
int main()
{
    LL a,b,n;
    while(scanf("%I64d %I64d %I64d %I64d",&a,&b,&n,&MOD)!=EOF){
        if(n==1){
            printf("%I64d\n",((LL)(a+ceil(sqrt(b*1.0)))%MOD));
            continue;
        }
        Mat pp;
        pp.n=pp.m=2;
        pp.mat[1][1]=a%MOD;
        pp.mat[1][2]=b%MOD;
        pp.mat[2][1]=1;
        pp.mat[2][2]=a%MOD;

        Mat A0;
        A0.n=2,A0.m=1;
        A0.mat[1][1]=a%MOD;
        A0.mat[2][1]=1;

        Mat ans=pp^(n-1);
        ans=ans*A0;
        printf("%I64d\n",(2*ans.mat[1][1])%MOD);
    }
    return 0;
}


/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         I have a dream!A AC deram!!
 orz orz orz orz orz orz orz orz orz orz orz
 orz orz orz orz orz orz orz orz orz orz orz
 orz orz orz orz orz orz orz orz orz orz orz

*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu5451(矩阵快速幂+广义斐波拉契)

题目链接:hdu5451 题目大意:已知,给你整数x,和一个素数M,求[y]%M。 题目分析: 设 (5+2√6)n=Xn+Yn*√6 Xn+Yn*√6 =(...
  • shutdown113
  • shutdown113
  • 2017年12月10日 17:06
  • 30

hdu2256Problem of Precision+矩阵快速幂+广义斐波拉契

Problem DescriptionInput The first line of input gives the number of cases, T. T test cases follow,...
  • xtulollipop
  • xtulollipop
  • 2016年08月31日 10:53
  • 211

hdu5451Best Solver=矩阵快速幂+广义斐波拉契

Problem Description The so-called best problem solver can easily solve this problem, with his/her c...
  • xtulollipop
  • xtulollipop
  • 2016年08月31日 11:08
  • 184

快速幂与快速矩阵幂(以大数下的斐波那契数列为例)

一般地,a^n的算法时间复杂度为o(n),但是如果n为大数,则运行时间过长,效率不高。因此,使用二分的思想降低时间复杂度,使其降至o(logn),则会使运行效率较大提升。二分思想如下图所示。 例如:2...
  • carson0408
  • carson0408
  • 2017年08月30日 22:03
  • 880

矩阵快速幂求斐波那契数列(初学整理)

参考文章:                  http://blog.csdn.net/u013795055/article/details/38599321                  htt...
  • NYIST_TC_LYQ
  • NYIST_TC_LYQ
  • 2016年10月31日 13:27
  • 7458

hdu-4549 M斐波那契数列【矩阵快速幂】

找规律写出f(2),f(3),f(4),f(5) .........可以发先 a b的系数是一系列的fib数列   如果可以求出fib数列 求快速幂就可以了    这样问题就在于如何求fib数列了 ...
  • a915800048
  • a915800048
  • 2016年04月19日 12:01
  • 243

poj 3070 Fibonacci 【矩阵快速幂 求第N个斐波那契数%1000】

Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11123   Acc...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015年08月30日 20:01
  • 2250

斐波拉契快速求法:矩阵快速幂

斐波拉契数:f0=0,f1=1,……..fn=f[n-1]+f[n-2] 用矩阵表示: 2*2的矩阵用结构体表示:struct node{ int a,b; int c,d; };...
  • daniel_csdn
  • daniel_csdn
  • 2016年03月01日 22:07
  • 171

算法学习笔记(五) 递归之 快速幂、斐波那契矩阵加速

递归就是直接或间接调用自身。算法思想:原问题可分解子问题(必要条件),原与分解后的子问题相似(递归方程),分解次数有限(子问题有穷),最终问题可直接解决(递归边界),经典问题有:幂运算、阶乘、组合数、...
  • thisinnocence
  • thisinnocence
  • 2014年08月17日 20:19
  • 3179

*递推 - 矩阵快速幂解斐波拉契数

题目:number number numberProblem DescriptionWe define a sequence F: F0=0,F1=1; Fn=Fn-1+Fn-2 (n≥2). ...
  • deaidai
  • deaidai
  • 2017年09月16日 19:42
  • 107
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu4565So Easy!+矩阵快速幂+广义斐波拉契
举报原因:
原因补充:

(最多只允许输入30个字)