[数学技巧 等比数列] 斐波那契k次幂和
来源:互联网 发布:手机相贯线软件 编辑:程序博客网 时间:2024/06/05 14:32
参考:http://blog.csdn.net/acdreamers/article/details/23039571
题意:给定和,其中,,求 的值。
首先k小的情况可以构造矩阵和向量[fi-1^k,fi-1^(k-1)*fi,fi-1^(k-2)*fi^2,....,fi^k,Sum]
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>using namespace std;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int M=55;const int P=1e9+9;struct Matrix{ int n; ll a[M][M]; Matrix(){ } Matrix(int in,int ii=0){ n=in; memset(a,0,sizeof(a)); if (ii) for (int i=0;i<=n;i++) a[i][i]=1; } ll *operator[](int x){ return a[x]; } friend Matrix operator* (Matrix A,Matrix B){ int n=A.n; Matrix ret(n); for (int i=0;i<=n;i++) for (int j=0;j<=n;j++) for (int k=0;k<=n;k++) (ret[i][j]+=A[i][k]*B[k][j]%P)%=P; return ret; }}A;Matrix Pow(Matrix A,int b){ Matrix ret(A.n,1); for (;b;b>>=1,A=A*A) if (b&1) ret=ret*A; return ret; }int n,K;ll C[M][M];inline void Pre(){ C[0][0]=1; for (int i=1;i<=K;i++){ C[i][0]=1; for (int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P; }}ll Ans;int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(K); Pre(); A=Matrix(K+1); for (int a=0;a<=K;a++) for (int t=0;t<=a;t++) A[a][K-a+t]=C[a][t]; A[K+1][K+1]=A[K+1][K]=1; A=Pow(A,n-1); for (int i=0;i<=K+1;i++) (Ans+=A[K+1][i])%=P; printf("%lld\n",Ans); return 0;}
然后对于这道变态的题
以下来自参考博文
分析:嗯,这道题貌似有难度,如果比较小的话我们可以构造矩阵,实际上这样做也挺麻烦的。
以前我们做一个大Fibonacci数列模一个大素数都是用矩阵,当然这里素数满足条件:5是模这个素数的二
次剩余,那么现在要求不要用矩阵来计算这个结果呢?那就是今天我要讨论的问题,本题也是基于这种思路。
本题我们可以直接利用Fibonacci数列的公式进行计算。因为我们知道Fibonacci数列的公式为:
虽然公式中含有根号,但是我们知道是一个整数,而且5是模1000000009的二次剩余。那么可以通过逆元
和二次剩余的转化来做。比如就可以用中的来代替。
为了方便表示,我们令:
那么得到
把按照二项式展开得到
对于每一个都这样表示,那么相同的合并后是等比数列,比如对于所有系数为合并后为
, 其中
所以到了这里本题就明确了,枚举每一个从0到,依次计算即可。
当然对于,我们可以阶乘预处理然后求逆元,至于和同样预处理,这样时间少很多。
可以看出本题条件好在1000000009是素数,而且5是模1000000009的二次剩余。
经计算2模1000000009的逆元是500000005,而的一个解为383008016。
也就是说对于有
同理,对于有
嗯,貌似还有一个问题没有处理,t = 1时咋办? 这个很简单啦,不用等比求和公式即可。其实吧,这里面
我们还可以注意到,也可以进一步优化,读者自己体会,就说到这里。
#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;const int P=1000000009;const int INV2=500000005;const int SQRT5=383008016;const int INVSQRT5=276601605;const int A=691504013;const int B=308495997;const int N=100005;ll n,K;ll fac[N],inv[N];ll pa[N],pb[N];inline void Pre(int n){ fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P; inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(P-P/i)*inv[P%i]%P; inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%P; pa[0]=1; for (int i=1;i<=n;i++) pa[i]=pa[i-1]*A%P; pb[0]=1; for (int i=1;i<=n;i++) pb[i]=pb[i-1]*B%P;}inline ll C(int n,int m){ return fac[n]*inv[m]%P*inv[n-m]%P;}inline ll Pow(ll a,ll b){ ll ret=1; for (;b;b>>=1,a=a*a%P) if (b&1) ret=ret*a%P; return ret;}inline ll Inv(ll x){ return Pow(x,P-2);}inline void Solve(){ ll Ans=0; for (int j=0;j<=K;j++){ ll t=pa[K-j]*pb[j]%P,tem; tem=t==1?n%P:t*(Pow(t,n)-1+P)%P*Inv(t-1)%P; if (~j&1) Ans+=C(K,j)*tem%P,Ans%=P; else Ans+=P-C(K,j)*tem%P,Ans%=P; } Ans=Ans*Pow(INVSQRT5,K)%P; printf("%lld\n",Ans);}int main(){ int T; freopen("t.in","r",stdin); freopen("t.out","w",stdout); Pre(100000); scanf("%d",&T); while (T--){ scanf("%lld%lld",&n,&K); Solve(); }}
- [数学技巧 等比数列] 斐波那契k次幂和
- hdu 1588 Gauss Fibonacci(斐波那契,等比数列求和,矩阵快速幂)
- [斐波那契 数学技巧] 洛谷 P1306 斐波那契公约数
- 斐波那契数列的通项公式推导<两次构造等比数列>
- python第四天 利用循环写出等比数列与斐波那契数列
- [斐波那契循环节 数学技巧] HDU 3977 Evil teacher
- [斐波那契前n位 数学技巧] HDU 1568 Fibonacci
- K-加强斐波那契
- 斐波那契第k项
- 【100题】斐波那契数列(3)-----数学归纳法
- 斐波那契,DP,递归,递推,数学归纳
- hdu 1865 1sting(数学:斐波那契+大数)
- hdoj 1568 (斐波那契数列+数学)
- 斐波那契数列 通项公式 [数学]
- 数学——洛谷 P1306 斐波那契公约数
- 斐波那契数的数学封闭式表示
- 51nod 1350 斐波那契表示 (数学)
- 递推递归练习 K 加强斐波那契
- HDFS文件读取
- 平衡的子集 【NOIP2016提高A组集训第4场11.1】
- C++中string的运用
- HTML CSS JS 特殊字符表
- LeetCode-----57. Insert Interval(数组插入并重新合并)
- [数学技巧 等比数列] 斐波那契k次幂和
- 《算法》第一章——数组的局部最小元素
- 360笔试题
- tjut 5901
- Ubuntu16.04安装遨游浏览器提示依赖关系不满足libgcrypt11的解决办法
- Activity与Fragment之间的通信
- [codeforces721E]Road to Home
- Kinect学习之KinectV2驱动在ubuntu14.04+ros上的安装
- UML之九图