zoukankan      html  css  js  c++  java
  • Solution -「国家集训队」「洛谷 P4451」整数的 lqp 拆分

    (mathcal{Description})

      Link.

      求

    [sum_{m>0\a_{1..m}>0\a_1+cdots+a_m=n}prod_{i=1}^mf_{a_i} ]

      其中 (f_i) 为 Fibonacci 数列第 (i) 项((f_0=0,f_1=1)),答案对 (10^9+7) 取模。

      (nle10^{10^4})

    (mathcal{Solution})

      记 (F(x))({f}) 的 OGF,首先来推导 (F(x))。根据定义 (f_{n+2}=f_{n+1}+f_n),可以发现经过适当位移,(F(x)) 能推出其自身而解出表达式。具体地:

    [egin{aligned} &~~~~~~~~~~~xF(x)+F(x)=frac{1}xF(x)-1\ &Rightarrow~~~~(x+1-frac{1}x)F(x)=-1\ &Rightarrow~~~~F(x)=frac{x}{1-x-x^2} end{aligned} ]

      令 (n) 的答案为 (g_n)(g_0=1)。简单 DP 得出递推式:

    [g_n=sum_{i=1}^nf_ig_{n-i} ]

      显然的卷积关系。令 ({g}) 的 OGF 为 (G(x)),则:

    [egin{aligned} G(x)&=1+G(x)F(x)\ &=frac{1}{1-F(x)}\ &=frac{1-x-x^2}{1-2x-x^2} end{aligned} ]

      提出一些常数:

    [Rightarrow~~~~G(x)=1-frac{x}{x^2+2x-1} ]

      我们想求 (g_n),即 ([x^n]G(x)),就得把上式最后一项分式结构配凑成等比数列求和的形式。首先暴力因式分解 (x^2+2x-1),用求根公式求出其两根:

    [x_{1,2}=frac{-2pm2sqrt{2}}{2}=-1pmsqrt2 ]

      所以 (x^2+2x-1=(x-x_1)(x-x_2))。代入 (G(x)) 的表达式:

    [egin{aligned} G(x)&=1-frac{x}{(x-x_1)(x-x_2)}\ &=1-frac{x}{x_1-x_2}left(frac{1}{x-x_1}-frac{1}{x-x_2} ight)\ &=1-frac{x}{x_1-x_2}left(frac{1}{x_2}sum_{i=0}^{+infty}frac{x^i}{x_2^i}-frac{1}{x_1}sum_{i=0}^{+infty}frac{x^i}{x_1^i} ight)\ &=1-frac{1}{x_1-x_2}sum_{i=1}^{+infty}(x_2^{-i}-x_1^{-i})x^i end{aligned} ]

      拆得清清楚楚啦,答案:

    [[x^n]G(x)=(x_2-x_1)^{-1}(x_2^{-n}-x_1^{-n}) ]

      代入 (x_{1,2})

    [[x^n]G(x)=-frac{sqrt2}4[(1-sqrt2)^n-(1+sqrt2)^n] ]

      最后 (sqrt2equiv 59713600equiv 940286407pmod{10^9+7}),所以可以 (mathcal O(log p+log n))(p) 是素模数)直接算出来。

    (mathcal{Code})

    /* Clearink */
    
    #include <cstdio>
    
    const int INV4 = 250000002, S2 = 59713600, MOD = 1e9 + 7;
    
    inline int rmod () {
    	int x = 0; char s = getchar ();
    	for ( ; s < '0' || '9' < s; s = getchar () );
    	for ( ; '0' <= s && s <= '9'; s = getchar () ) {
    		x = ( x * 10ll + ( s ^ '0' ) ) % ( MOD - 1 );
    	}
    	return x;
    }
    
    inline int mul ( const long long a, const int b ) { return a * b % MOD; }
    inline int sub ( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
    inline int add ( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
    inline int mpow ( int a, int b ) {
    	int ret = 1;
    	for ( ; b; a = mul ( a, a ), b >>= 1 ) ret = mul ( ret, b & 1 ? a : 1 );
    	return ret;
    }
    
    int main () {
    	int n = rmod ();
    	printf ( "%d
    ", sub ( 0, mul ( mul ( S2, INV4 ),
    		sub ( mpow ( sub ( 1, S2 ), n ), mpow ( add ( 1, S2 ), n ) ) ) ) );
    	return 0;
    }
    
    
  • 相关阅读:
    RabbitMQ教程
    设置文件夹共享及所有访问权限
    一键操作IIS
    C#操作IIS服务
    【01】浅谈HTTP在WebApi开发中的运用
    Socket通信原理
    C# 通过JObject解析json对象
    MVC小知识整理
    Global.asax文件的作用
    iOS开发日记9-终端命令
  • 原文地址:https://www.cnblogs.com/rainybunny/p/14253326.html
Copyright © 2011-2022 走看看