比较水的一题。居然是一道没看题解就会做的黑题……
题目链接:洛谷
题目大意:定义一个长度为 $m$ 的正整数序列 $a$ 的价值为 $prod f_{a_i}$。($f$ 是斐波那契数)对于每一个 $sum a_i=n$ 的正整数序列,求出它们的价值之和。
$1le nle 10^6$。
这题一看就是生成函数瞎搞。
令 $F$ 为 $f$ 的生成函数。
那么有 $F=x imes F+x^2 imes F+x$。
就有 $F=dfrac{x}{1-x-x^2}$。
答案即为 $sum^{infty}_{i=0}F^i(x)[x^n]$。(注意的是不是 $F^n(x)[x^n]$,因为 $f_0=0$)
等比数列:$dfrac{1}{1-F(x)}[x^n]$。
套进去:
$$dfrac{1}{1-dfrac{x}{1-x-x^2}}[x^n]$$
$$dfrac{1-x-x^2}{(1-x-x^2)-x}[x^n]$$
$$dfrac{1-2x-x^2+x}{1-2x-x^2}[x^n]$$
$$(1+dfrac{x}{1-2x-x^2})[x^n]$$
$$dfrac{x}{1-2x-x^2}[x^n]$$
这个生成函数似乎与 $F$ 长得有点像……令它为 $G$,是数列 $g$ 的生成函数。要求即为 $g[n]$。
$(1-2x-x^2)G=x$
$G=2x imes G+x^2 imes G+x$
那么就有 $g[0]=0,g[1]=1,g[i]=2g[i-1]+g[i-2](ige 2)$。
此时可以用矩阵快速幂做到 $O(log n)$。但是这么小的 $n$……
时间复杂度 $O(n)$。
#include<bits/stdc++.h> using namespace std; const int maxn=1000100,mod=1000000007; #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define ROF(i,a,b) for(int i=(a);i>=(b);i--) #define MEM(x,v) memset(x,v,sizeof(x)) inline int read(){ int x=0,f=0;char ch=getchar(); while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return f?-x:x; } int n,g[maxn]; int main(){ n=read(); g[0]=0;g[1]=1; FOR(i,2,n) g[i]=(2ll*g[i-1]+g[i-2])%mod; printf("%d ",g[n]); }