Loading

题解 P4451 【[国家集训队]整数的lqp拆分】

题意

\[\large{\sum_{\small\sum_{i=1}^ma_i=n,a_i>0}}\small\prod_{i=1}^m F_{a_i} \]

题解

小清新生成函数。

记斐波那契数列的第\(i\)项为\(fib_i\),那么有:\(fib_0=0,fib_1=1,fib_n=fib_{n-1}+fib_{n-2}\)

\(F(x)=\sum_{i=0}^{+\infty}fib_ix^i\),即斐波那契的生成函数,那么显然有:

\[\begin{alignedat}{2} F(x)&=fib_0+&fib_1\times x+&fib_2\times x^2+fib_3\times x^3+fib_4\times x^4+\ldots(1)\\ xF(x)&=&fib_0\times x+&fib_1\times x^2+fib_2\times x^3+fib_3\times x^4+\ldots(2)\\ x^2F(x)&=&&fib_0\times x^2+fib_1\times x^3+fib_2\times x^4+\ldots(3)\\ \end{alignedat} \]

\((2)\)式加\((3)\)式,由于\(fib_i+fib_{i+1}=fib_{i+2}\),可以得到:

\[(x+x^2)F(x)=fib_2\times x^2+fib_3\times x^3+fib_4\times x^4\ldots \]

\((1)\)式对比一下,有:

\[F(x)=(x+x^2)F(x)+x \]

\[F(x)=\frac{x}{1-x-x^2} \]

\(n\)的答案为\(g_n\),递推式应该比较容易。就是枚举最后的一个数字,在原来的基础上乘上这个数的斐波那契值,在累加答案,最后的式子应该就是:

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

特别地,我们令\(g_0=1\)

\[g_n=[n=0]+\sum_{i=1}^ng_ifib_{n-i} \]

\(g\)的生成函数为\(G\),即\(G(x)=\sum_{i=0}^{+\infty}g_ix^i\),那么对其进行展开:

\[G(x)=\sum_{n=0}^{+\infty}([n=0]+\sum_{i=1}^ng_ifib_{n-i})x^n \]

\[G(x)=1+\sum_{n=1}^{+\infty}(\sum_{i=1}^ng_ifib_{n-i})x^n \]

不难发现,\(\sum_{n=1}^{+\infty}(\sum_{i=1}^ng_ifib_{n-i})x^n=F(x)\times G(x)\),因此:

\[G(x)=1+F(x)\times G(x) \]

\[G(x)=\frac{1}{1-F(x)}=\frac{1}{1-\frac{1}{1-x-x^2}} \]

\[=\frac{1-x-x^2}{1-2x-x^2}=1-\frac{x}{x^2+2x-1} \]

此时只需要展开\(-\frac{x}{x^2+2x-1}\)即可。

我们知道,\(\frac{1}{1-cx^k}=\sum_{i=0}^{+\infty}(cx)^{ik}\),因此我们希望上式可以用这样的方式展开。

我们只需要解出\(x^2+2x-1=0\)的两根\(x_1,x_2\)\(x_{1,2}=-1±\sqrt{2}\),那么就有:

\[-\frac{x}{x^2+2x-1}=-\frac{x}{(x-x_1)(x-x_2)} \]

\[=\frac{x}{x_2-x_1}(\frac{1}{x-x_1}-\frac{1}{x-x_2}) \]

把常数项化为\(1\)

\[=\frac{x}{x_2-x_1}(\frac{1}{x2}\times\frac{1}{1-x/x2}-\frac{1}{x1}\times\frac{1}{1-x/x1}) \]

\[=\frac{x}{x_2-x_1}(\frac{1}{x2}\times\sum_{i=0}\frac{x^i}{x_2^i}-\frac{1}{x1}\times\sum_{i=0}\frac{x^i}{x_1^i}) \]

\[=\frac{1}{x_2-x_1}(\sum_{i=0}\frac{x^{i+1}}{x_2^{i+1}}-\sum_{i=0}\frac{x^{i+1}}{x_1^{i+1}}) \]

那么第\(n\)项的系数为\(g(n)=\dfrac{1}{x2-x1}\times(\dfrac{1}{x_2^n}-\dfrac{1}{x_1^n})\)

代入得到:\(g(n)=\dfrac{\sqrt{2}}{4}[(1+\sqrt{2})^n-(1-\sqrt{2})^n]\)

\(\sqrt2\)在模\(1000000007\)时等于\(59713600\)\(940286407\)

但是由于\(n\)的值很大,根据费马小定理,对\(mod-1\)取模即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<const int mod> 
struct modint{
    ll x;
    modint(ll o=0){x=o;}
    modint &operator = (ll o){return x=o,*this;}
    modint &operator +=(modint o){return x=x+o.x>=mod?x+o.x-mod:x+o.x,*this;}
    modint &operator -=(modint o){return x=x-o.x<0?x-o.x+mod:x-o.x,*this;}
    modint &operator *=(modint o){return x=1ll*x*o.x%mod,*this;}
    modint &operator ^=(ll b){
    	b%=(mod-1);
        modint a=*this,c=1;
        for(;b;b>>=1,a*=a)if(b&1)c*=a;
        return x=c.x,*this;
    }
    modint &operator /=(modint o){return *this *=o^=mod-2;}
    modint &operator +=(ll o){return x=x+o>=mod?x+o-mod:x+o,*this;}
    modint &operator -=(ll o){return x=x-o<0?x-o+mod:x-o,*this;}
    modint &operator *=(ll o){return x=1ll*x*o%mod,*this;}
    modint &operator /=(ll o){return *this *= ((modint(o))^=mod-2);}
    template<class I>friend modint operator +(modint a,I b){return a+=b;}
    template<class I>friend modint operator -(modint a,I b){return a-=b;}
    template<class I>friend modint operator *(modint a,I b){return a*=b;}
    template<class I>friend modint operator /(modint a,I b){return a/=b;}
    friend modint operator ^(modint a,ll b){return a^=b;}
    friend bool operator ==(modint a,ll b){return a.x==b;}
    friend bool operator !=(modint a,ll b){return a.x!=b;}
    bool operator ! () {return !x;}
    modint operator - () {return x?mod-x:0;}
    void read(){
    	string s;cin>>s;x=0;
    	for(int i=0;i<s.length();i++)
			*this*=10,*this+=s[i]-'0';
	}void write(){
		cout<<x;
	}
};
modint<1000000006>n;
modint<1000000007>ans,sqrt2=59713600;
signed main(){
	n.read();
	ans=sqrt2/4*(((sqrt2+1)^n.x)-((-sqrt2+1)^n.x));ans.write();
	return 0;
}
posted @ 2020-12-30 19:47  caigou233  阅读(87)  评论(0编辑  收藏  举报