暑假训练数论

斐波那契  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说的是否正确。

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,...)

猜你喜欢

转载自www.cnblogs.com/wpbing/p/9438679.html