我想按顺序 (1) 或 (nlogn) 顺序生成序列 1,3,8,22,60 ,164 的第 n 项

I want to generate the nth term of the sequence 1,3,8,22,60 ,164 in Order(1) or order of (nlogn)

本文关键字:顺序 的第 nlogn      更新时间:2023-10-16

此序列满足a(n+2) = 2 a(n+1) + 2 a(n)。

还有a(n)=[(1

+sqrt(3))^(n+2)-(1-sqrt(3))^(n+2)]/(4sqrt(3)).

我正在使用C++ n 可以从 1 到 10^ 9 不等。我需要答案模 (10^9)+7但是速度在这里非常重要

我的公式 1 代码对于 10^7>的数字很慢

#include <iostream>
#define big unsigned long long int
#include<stdlib.h>
int ans[100000001]={0};
big m  =1000000007;
using namespace std;
int main()
{
    //cout << "Hello world!" << endl;
    big t,n;
    cin>>t;
    big a,b,c;
    a=1;
    b=3;
    c=8;
    ans[0]=0;
    ans[1]=1;
    ans[2]=3;
    ans[3]=8;
    for(big i=3;i<=100000000;i++)
        {
            ans[i]=(((((ans[i-2])+(ans[i-1])))%m)<<1)%m;
        }
//    while(t--)
//    {
//        int f=0;
//        cin>>n;
//        if(n==1){
//        cout<<1<<endl;f++;}
//        if(n==2){
//        cout<<3<<endl;
//        f++;
//        }
//        if(!f){
//        a=1;
//        b=3;
//        c=8;
//        for(big i=3;i<=n;i++)
//        {
//            c=(((((a)+(b
//                         )))%m)<<1)%m;
//            a=b%m ;
//            b=c%m;
//        }
//        cout<<ans[n]<<endl;
//        }
//    }
while(t--)
{
    cin>>n;
    if(n<=100000000)
    cout<<ans[n]<<endl;
    else
    cout<<rand()%m;
}
    return 0;
}

我想要一个更快的方法。如何使用第二个公式计算第 n 项。有什么技巧可以非常快速地计算小数的模功率吗?您对更快地生成此序列有什么建议吗?

请帮忙

您可以使用矩阵方法计算具有线性递归关系的序列值,以 O(log n) 步长。在这种情况下,递归矩阵为

2 2
1 0
然后,通过将

矩阵的 n 次幂乘以两个初始值来获得序列的第 n 项。

复发立即转化为

|x_n    |   |2 2|   |x_(n-1)|
|x_(n-1)| = |1 0| * |x_(n-2)|

因此

|x_(n+1)|   |2 2|^n   |x_1|
|x_n    | = |1 0|   * |x_0|.

在这种情况下,初始条件给出,x_1 = 1, x_2 = 3导致x_0 = 0.5,一个非整数值,因此计算应该是

|x_(n+1)|   |2 2|^(n-1)   |x_2|
|x_n    | = |1 0|       * |x_1|.

要获得某个数字取模的值,请计算矩阵取模该数的幂。

我不想破坏探索算法难题解决方案的乐趣,所以我只给你一个开始提示:你那里基本上是一个斐波那契数列,有一些令人困惑的元素。