斐波那契 https://www.cnblogs.com/Milkor/p/4734763.html
通项公式
求证过程就算了
斐波那契和矩阵的关系:
实现过程是根据快速幂改编的
void fen(ll r[][2],ll k[][2])//矩阵乘法 { ll ans[2][2]; ans[0][0]=(r[0][0]*k[0][0]%mod+r[0][1]*k[1][0]%mod)%mod; ans[0][1]=(r[0][0]*k[0][1]%mod+r[0][1]*k[1][1]%mod)%mod; ans[1][0]=(r[1][0]*k[0][0]%mod+r[1][1]*k[1][0]%mod)%mod; ans[1][1]=(r[1][0]*k[0][1]%mod+r[1][1]*k[1][1]%mod)%mod; r[0][0]=ans[0][0],r[0][1]=ans[0][1],r[1][0]=ans[1][0],r[1][1]=ans[1][1]; } ll fbnq(ll num) { if(num==0) return 0; ll k[2][2]={1,0,0,1};//k[0][1]为f[n],k[1][1]为f[n-1]; ll r[2][2]={1,1,1,0}; while(num>1) { if(((num&1)!=0)) fen(k,r); fen(r,r);//思想可以参考快速幂 num>>=1; } fen(r,k); return r[0][1]; }
一些常用性质
例题
2007年到来了。经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来。
接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了。所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住。于是他决定编写一个程序来测验zouyu说的是否正确。
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来。
接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了。所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住。于是他决定编写一个程序来测验zouyu说的是否正确。
Input输入若干数字n(0 <= n <= 100000000),每个数字一行。读到文件尾。Output输出f[n]的前4个数字(若不足4个数字,就全部输出)。Sample Input
0 1 2 3 4 5 35 36 37 38 39 40
Sample Output
0 1 1 2 3 5 9227 1493 2415 3908 6324 1023
数字有点大,递推不行,可以运用公式,但要求前4位,可以
log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;
log10(1.0234432)就是log10(10234432)的小数部分.
log10(1.0234432)=0.010063744
10^0.010063744=1.023443198
#include<iostream> #include<cmath> #include<string.h> using namespace std; int f[20]; int main() { int n; double s; f[0]=0,f[1]=1; for(int i=2;i<20;i++) f[i]=f[i-1]+f[i-2]; while(cin>>n) { if(n<20) { cout<<f[n]<<endl; continue; } s=log10(1.0/sqrt(5.0))+n*log10((1+sqrt(5.0))/2); s=s-(int)s; s=pow(10,s); while(s<1000) s*=10; cout<<(int)s<<endl; } }
We all know the definition of Fibonacci series: fib[i]=fib[i-1]+fib[i-2],fib[1]=1,fib[2]=1.And we define another series P associated with the Fibonacci series: P[i]=fib[4*i-1].Now we will give several queries about P:give two integers L,R, and calculate ∑P[i](L <= i <= R).
InputThere is only one test case.
The first line contains single integer Q – the number of queries. (Q<=10^4)
Each line next will contain two integer L, R. (1<=L<=R<=10^12)OutputFor each query output one line.
Due to the final answer would be so large, please output the answer mod 1000000007.Sample Input
2 1 300 2 400
Sample Output
838985007 352105429
题意:sum[i]=fib[4*i-1] 给出L,R,求出中间的p[i]的和。
Sum[i]=Fib[3]+Fib[7]+......+Fib[4i-1],
因为Fib[m+n-1]=Fib[m-1]*Fib[n-1]+Fib[m]*Fib[n]
所以Fib[4i-1]=Fib[2i+2i-1]=Fib[2i-1]*Fib[2i-1]+Fib[2i]*Fib[2i]
所以Sum[i]=Fib[1]*Fib[1]+Fib[2]*Fib[2]+......+Fib[2i]*Fib[2i]
又Fib[i]*Fib[i+1]+Fib[i+1]*Fib[i+1]=Fib[i+1]*Fib[i+2]
代入计算可得Sum[i]=Fib[2i]*Fib[2i+1]-Fib[0]*Fib[1]=Fib[2i]*Fib[2i+1]
最后发现Sum[i]只和fibonacci的两项有关。
关于fibonacci数列的一项可以构造矩阵在O(logn)时间内算出。
#include<iostream> #include<cstdio> #include<string.h> #include<algorithm> using namespace std; #define mod 1000000007 #define ll long long void fen(ll r[][2],ll k[][2]) { ll ans[2][2]; ans[0][0]=(r[0][0]*k[0][0]%mod+r[0][1]*k[1][0]%mod)%mod; ans[0][1]=(r[0][0]*k[0][1]%mod+r[0][1]*k[1][1]%mod)%mod; ans[1][0]=(r[1][0]*k[0][0]%mod+r[1][1]*k[1][0]%mod)%mod; ans[1][1]=(r[1][0]*k[0][1]%mod+r[1][1]*k[1][1]%mod)%mod; r[0][0]=ans[0][0],r[0][1]=ans[0][1],r[1][0]=ans[1][0],r[1][1]=ans[1][1]; } ll fbnq(ll num) { if(num==0) return 0; ll k[2][2]={1,0,0,1}; ll r[2][2]={1,1,1,0}; while(num>1) { if(((num&1)!=0)) fen(k,r); fen(r,r); num>>=1; } fen(r,k); return r[0][1]; } int main() { int t; cin>>t; while(t--) { ll l,r; ll sl=0,sr=0; cin>>l>>r; l--; sl=fbnq(2*l)*fbnq(2*l+1); sr=fbnq(2*r)*fbnq(2*r+1); cout<<((sr-sl)%mod+mod)%mod<<endl; } }
卡特兰数
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n>=2)
例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
h(n)=h(n-1)*(4*n-2)/(n+1);
递推关系的解为:
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
递推关系的另类解为:
h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...)