zoukankan      html  css  js  c++  java
  • The Nth Item【斐波那契】

    题意:

    给出递推式 (F)

    [F(0)=0,F(1)=1 ]

    [F(n)=3*F(n-1)+2*F(n-2)(ngeq2) ]

    给出查询次数:(Q) 和第一次查询的数 (N),每次查询的答案为:(A_i=F(N))。并且(N_i=N_{i-1} xor A_{i-1}^2),最后要求输出:(A_1 xor A_2 ... xor A_Q)
    题目链接:https://nanti.jisuanke.com/t/41355

    分析:

    (1) (N) 的范围很大,直接算肯定算不出来,但因为数据比较水,所以用 (map) 记忆化一下就可以。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int mod=998244353;
    typedef long long ll;
    unordered_map<ll,ll>mp;
    struct matrix
    {
        ll mat[3][3];
        void zero()
        {
            for(int i=1;i<=2;i++)
                for(int j=1;j<=2;j++)
                    mat[i][j]=0;
        }
        void eye()
        {
            for(int i=1;i<=2;i++)
                mat[i][i]=1;
        }
        matrix operator * (const matrix &mt)const
        {
            matrix res;
            res.zero();
            for(int i=1;i<=2;i++)
            {
                for(int k=1;k<=2;k++)
                {
                    if(mat[i][k])
                    {
                        for(int j=1;j<=2;j++)
                            res.mat[i][j]=(res.mat[i][j]+mat[i][k]*mt.mat[k][j]%mod)%mod;
                    }
                }
            }
            return res;
        }
    };
    matrix mpower(matrix m,ll b)
    {
        matrix res;
        res.zero();
        res.eye();
        while(b)
        {
            if(b&1) res=res*m;
            m=m*m;
            b>>=1;
        }
        return res;
    }
    void init(matrix &a)
    {
        a.zero();
        a.mat[1][1]=1;
    }
    void init2(matrix &a)
    {
        a.zero();
        a.mat[1][1]=3;
        a.mat[1][2]=1;
        a.mat[2][1]=2;
    }
    int main()
    {
        ll a,ans=0,q,n;
        scanf("%lld%lld",&q,&n);
        matrix A,B,t;
        init(A);
        init2(B);
        while(q--)
        {
            if(mp.count(n))
                a=mp[n];
            else
                t=A*mpower(B,n-1);
            a=t.mat[1][1];
            mp[n]=a;
            n=n^(a*a);
            ans=ans^a;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    

    (2)可以求出循环节求解
    (3)斐波那契数列的通项公式:

    [F(n)=frac{1}{sqrt{17}}(frac{3+sqrt{17}}{2})^n-frac{1}{sqrt{17}}(frac{3-sqrt{17}}{2})^n ]

    (sqrt{17}) 在模 (p) 意义下等价于 (17)(p) 的二次剩余,本题中这个值存在且是一个整数;但依然会多一个快速幂的 (log),这里 (n) 可以用欧拉降幂降到 (2e9) 以内。
    (N=sqrt{2e9})(n=k*N+r),有 (x^n=x^{k*N}*x^r),注意到 (kleq N,rleq N),预处理出最后的两部分就可以 (O(1)) 查询出 (F(n))

    参考博客

  • 相关阅读:
    css知识点
    javascript 中闭包
    javascript 继承方法总结
    css滚动滚轮事件
    关于闭包的总结
    xpth xslt
    好的js函数
    自动化测试实施(4)
    自动化测试实施(5)
    自动化测试实施(3)
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13252206.html
Copyright © 2011-2022 走看看