之前看过cmd的blog,还算有点生成函数基础了,所以这题还能动。
设 (F(x)=f_ix^i) ,(f_i) 表示斐波那契数列第 (i) 项((f_0=0,f_1=1,f_i=f_{i-1}+f_{i-2})) ,那么答案就是
[G(x)=sum_{k=0} F^k(x)=dfrac{1}{1-F(x)}
]
这个应该很好理解,枚举用了 (k) 个数就可以得到上式。
斐波那契的生成函数可以用如下方法计算
[F(x)=f_0+f_1x+f_2x^2+f_3x^3+f_4x^4+cdots\
xF(x)=f_0x+f_1x^2+f_2x^3+f_3x^4+cdots\
x^2F(x)=f_0x^2+f_1x^3+f_2x^4+cdots\
]
结合 (f_i=f_{i-1}+f_{i-2}) 得:
[F(x)-f_0-f_1x=xF(x)-f_0x+x^2F(x)\
F(x)-x=xF(x)+x^2F(x)\
(x^2+x-1)F(x)+x=0\
F(x)=dfrac{x}{1-x-x^2}
]
带到最开头那个式子得到答案的生成函数
[G(x)=dfrac{1}{1-F(x)}\
=dfrac{1}{1-dfrac{x}{1-x-x^2}}\
=dfrac{1-x-x^2}{1-x-x^2-x}\
=dfrac{1-x-x^2}{1-2x-x^2}\
=1-dfrac{x}{1-2x-x^2}
]
这个封闭告诉不了我们什么东西,要化简。(跟着cmd的方法学的)
尝试因式分解分母尝试化成一堆 (dfrac{1}{1-qx^k}) 相加的形式。
设 (1-2x-x^2=0) 的两根为 (x_1,x_2) ((x_1=-1-sqrt{2},x_2=-1+sqrt{2}))
有
[dfrac{1}{x-x_1}-dfrac{1}{x-x_2}=dfrac{x_1-x_2}{(x-x_1)(x-x_2)}
]
[G(x)=1-dfrac{x}{(x-x_1)(x-x_2)}\
=1-dfrac{x}{x_1-x_2}(dfrac{1}{x-x_1}-dfrac{1}{x-x_2})\
=1-dfrac{x}{x_1-x_2}(dfrac{1}{x_2}dfrac{1}{1-frac{1}{x_2}}+dfrac{1}{x_1}dfrac{1}{1-frac{1}{x_1}})\
=1-dfrac{1}{x_1-x_2}(sum_{i=0}dfrac{x^{i+1}}{x_2^{i+1}}-sum_{i=0}dfrac{x_{i+1}}{x_1^{i+1}})
]
提取第 (n) 项系数
[[x^n]G(x)=dfrac{1}{x_2-x_1}(dfrac{1}{x_2^{n}}-dfrac{1}{x_1^n})\
=dfrac{1}{2sqrt{2}}((1+sqrt{2})^{n}-(1-sqrt{2})^{n})
]
写个程序暴力 for
一遍,1 min
内绝对能跑出 (sqrt{2}mod 10^9+7) ,然后快速幂算就好了。
实测 2.47s
,本地可以优化乱开,都开上会快很多。。。
你可能会好奇那个 (1) 哪里去了。我tm都做了三道生成函数了还在想这个问题,那个 (1) 是加在 ([x^0]) 上的。所以我手动带入 (n=3) 发现那个式子已经等于 (5) 了人都傻了(样例),后来才反应过来。
读入时候根据费马小定理 (nmod (mod-1))
艹这种题我能挂3发
两行求 (sqrt{2}mod 10^9+7)
#define mod 1000000007
signed main(){for(int i=1;;++i)if(1ll*i*i%mod==2){cout<<i<<'
';return 0;}}
然后偷懒 #define int long long
了。
#define int long long
#define mod 1000000007
const int is2=59713600;
inline int modread(const int&p){
int x=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))x=(x*10ll+ch-'0')%p,ch=getchar();
return x;
}
inline int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
signed main(){
int n=modread(mod-1),ans=(qpow(1+is2,n)-qpow(mod+1-is2,n)+mod)%mod*qpow(is2*2%mod,mod-2)%mod;
cout<<ans<<'
';
}