根据题意:最后一步是寻求f(b) + f(k + b) + f(2 * k + b) + …+ f((n-1) * k + b)

清除f(b) = A^b

间A =

1 1

1 0

所以sum(n - 1) = A^b(E + A^ k + A ^(2 * k) + … + A ^((n - 1) * k)

设D = A^k

sum(n-1) = A^b(E + D + D ^ 2 + … + D ^(n - 1))

括号中的部分就能够二分递归求出来了

而单个矩阵就能够用矩阵高速幂求出来

/*************************************************************************
> File Name: hdu1588.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年03月12日 星期四 18时25分07秒
************************************************************************/ #include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL; LL mod, k, b; class MARTIX
{
public:
LL mat[3][3];
MARTIX();
MARTIX operator * (const MARTIX &b)const;
MARTIX operator + (const MARTIX &b)const;
MARTIX& operator = (const MARTIX &b);
}A, E, D; MARTIX :: MARTIX()
{
memset (mat, 0, sizeof(mat));
} MARTIX MARTIX :: operator * (const MARTIX &b)const
{
MARTIX ret;
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 2; ++j)
{
for (int k = 0; k < 2; ++k)
{
ret.mat[i][j] += this -> mat[i][k] * b.mat[k][j];
ret.mat[i][j] %= mod;
}
}
}
return ret;
} MARTIX MARTIX :: operator + (const MARTIX &b)const
{
MARTIX ret;
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 2; ++j)
{
ret.mat[i][j] = this -> mat[i][j] + b.mat[i][j];
ret.mat[i][j] %= mod;
}
}
return ret;
} MARTIX& MARTIX :: operator = (const MARTIX &b)
{
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 2; ++j)
{
this -> mat[i][j] = b.mat[i][j];
}
}
return *this;
} MARTIX fastpow(MARTIX ret, LL n)
{
MARTIX ans;
ans.mat[0][0] = ans.mat[1][1] = 1;
while (n)
{
if (n & 1)
{
ans = ans * ret;
}
n >>= 1;
ret = ret * ret;
}
return ans;
} void Debug(MARTIX A)
{
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 2; ++j)
{
printf("%lld ", A.mat[i][j]);
}
printf("\n");
}
} MARTIX binseach(LL n)
{
if (n == 1)
{
return D;
}
MARTIX nxt = binseach(n >> 1);
MARTIX B = fastpow(D, n / 2);
B = B + E;
nxt = nxt * B;
if (n & 1)
{
MARTIX C = fastpow(D, n);
nxt = nxt + C;
}
return nxt;
} int main()
{
LL n;
E.mat[0][0] = E.mat[1][1] = 1;
A.mat[0][0] = A.mat[0][1] = A.mat[1][0] = 1;
// Debug(A);
while (~scanf("%lld%lld%lld%lld", &k, &b, &n, &mod))
{
if (n == 1)
{
MARTIX x = fastpow(A, b);
printf("%lld\n", x.mat[0][1]);
continue;
}
D = fastpow(A, k);
MARTIX ans = binseach(n - 1);
ans = ans + E;
MARTIX base = fastpow(A, b);
ans = base * ans;
// Debug(ans);
printf("%lld\n", ans.mat[0][1]);
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

hdu1588---Gauss Fibonacci(矩阵,线性复发)的更多相关文章

  1. HDU 1588 Gauss Fibonacci(矩阵快速幂)

    Gauss Fibonacci Time Limit: 3000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) ...

  2. POJ3233]Matrix Power Series && [HDU1588]Gauss Fibonacci

    题目:Matrix Power Series 传送门:http://poj.org/problem?id=3233 分析: 方法一:引用Matrix67大佬的矩阵十题:这道题两次二分,相当经典.首先我 ...

  3. HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)

    Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very cle ...

  4. HDU:Gauss Fibonacci(矩阵快速幂+二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=1588 Problem Description Without expecting, Angel replied ...

  5. HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

    HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意:  g(i)=k*i+b;i为变量.  给出 ...

  6. hdu1588之经典矩阵乘法

    Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 1588(Fibonacci矩阵求和)

    题目的大意就是求等差数列对应的Fibonacci数值的和,容易知道Fibonacci对应的矩阵为[1,1,1,0],因为题目中f[0]=0,f[1]=1,所以推出最后结果f[n]=(A^n-1).a, ...

  8. BZOJ3286 Fibonacci矩阵 矩阵 快速幂 卡常

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3286 题意概括 n,m,a,b,c,d,e,f<=10^1000000 题解 神奇的卡常题目 ...

  9. hdu1588:Gauss Fibonacci

    对每个0<=i<n求f(g(i))的和,其中f(x)为斐波那契数列第x项,g(i)=k*i+b,k,b,n给定,模数给定. 斐波那契数有一种用矩阵乘法求的方法,这个矩阵A自己写,令F[i] ...

随机推荐

  1. Effective C++:条款25:考虑写出一个不抛异常的swap函数

    (一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...

  2. Test SRM Level One: TemperatureScales

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=6038 因为TopCoder SRM比赛使用的编译器进行了升级, ...

  3. c#并行任务多种优化方案分享(异步委托)

    遇到一个多线程任务优化的问题,现在解决了,分享如下. 假设有四个任务: 任务1:登陆验证(CheckUser) 任务2:验证成功后从Web服务获取数据(GetDataFromWeb) 任务3:验证成功 ...

  4. C#判断操作系统是32位还是64位(超简单)

    由于项目需要在64位和32位系统运行,需要判断当前系统是32位还是64位. 网上很多方法,但是都感觉不是很简洁,最后发现可以使用int的长度来判断:看代码 /// <summary>    ...

  5. wpf做的3d滑动gallery

    原文:wpf做的3d滑动gallery wpf做的3d滑动gallery 随着iphone\ipad的流行及热捧,现在做移动产品不管是什么平台的,领导总想做成像ios系统的样子.自从微软发布了wind ...

  6. 聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析

    1. 引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把 ...

  7. CSAPP 六个重要的实验 lab5

    CSAPP  && lab5 实验指导书: http://download.csdn.net/detail/u011368821/7951657 实验材料: http://downlo ...

  8. 关于csrss.exe和winlogon.exe进程多、占用CPU高的解决办法

    原地址 http://blog.sina.com.cn/s/blog_912e77480101nuif.html   最近VPS的CPU一直处在100%左右,后台管理上去经常打不开,后来发现上远程都要 ...

  9. Linux/UNIX数据文件和信息系统

    数据文件和信息系统 密码文件 在存储/etc/passwd在.以下功能可以用来获得密码文件条目. #include <sys/types.h> #include <pwd.h> ...

  10. oracle的unique约束

    unique约束是唯一性约束,对于需要列类型应用程序会重复出现分歧值.您可以加入一个单独的列unique约束.能够加入多个列unique约束().假设为多个列加入一个unique约束,仅仅须要保证这多 ...