zoukankan      html  css  js  c++  java
  • 【洛谷4451】[国家集训队] 整数的lqp拆分(生成函数水题)

    点此看题面

    • (F(x))为斐波那契数列的生成函数,求(sum_{i=1}^{+infty}F(x)^i)(n)次项系数。
    • (nle10^{10^5})

    生成函数

    利用等比数列求和公式得到:

    [sum_{i=1}^{+infty}F(x)^i=frac{F(x)}{1-F(x)} ]

    众所周知(F(x)=frac x{1-x-x^2}),于是原式等价于:

    [frac x{1-2x-x^2} ]

    然后我们仿照推斐波那契数列通项公式的方式来推一推它的通项公式。(具体方法可详见初学生成函数(二)——生成函数与斐波那契数列,这里就写得简略一些了)

    首先把分母变个形得到:

    [frac x{(1-Ax)(1-Bx)} ]

    解得(A=1+sqrt2,B=1-sqrt2)

    然后把它裂开得到:

    [frac{frac A{2sqrt2}x}{1-Ax}-frac{frac B{2sqrt2}x}{1-Bx} ]

    (Ax,Bx)看作整体反向利用等比数列求和公式得到:

    [F(x)=sum_{i=1}^{infty}frac{A^i-B^i}{2sqrt2}x^i ]

    所以第(n)项系数为:

    [frac{(1+sqrt2)^n-(1-sqrt2)^n}{2sqrt2} ]

    在模(10^9+7)意义下有(sqrt2=59713600),那么就可以直接快速幂计算了。

    一个小技巧,对于质数(p)(a^nequiv a^{n\%(p-1)}(mod p))恒成立,所以我们可以在读入的同时将(n)(10^9+6),就可以避免高精了。

    代码:(O(logX))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define X 1000000007
    #define I2 500000004
    #define S2 59713600
    using namespace std;
    int n;I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
    int main()
    {
    	char c;W(!isdigit(c=getchar()));W(n=(10LL*n+(c&15))%(X-1),isdigit(c=getchar()));//读入同时取模
    	return printf("%d
    ",1LL*(QP(1+S2,n)-QP(1-S2+X,n)+X)*QP(S2<<1,X-2)%X),0;//快速幂计算答案
    }
    
  • 相关阅读:
    第二阶段每日总结01
    第十二周进度条
    构建之法阅读笔记05
    找水王01
    第十一周进度条
    第十周进度条
    构建之法阅读笔记04
    第九周进度条
    每日工作总结10
    每日工作总结09
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu4451.html
Copyright © 2011-2022 走看看