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

· · 题解

    设 g[i] 为i的lqp拆分的权值和,则 g[i] = ∑f[j] * g[i-j] + f[i], 其中 g[0] = 0, g[1] = 1.
    设 A = ∑f[i] * x^i , B = ∑g[i] * x^i ,那么 => B = A*B + A.
    解一下 B ,发现 B = A/(1-A);
    又∵ A的闭形式是 x/(1 - x - x^2) [斐波那契数的生成函数闭形式].
    ∴  B = x/(1 - 2x - x^2) ,于是直接由B的特征根 得出g[]的递推式 => g[i] = 2*g[i-1] + g[i-2]. 

    (生成函数太好用了2333)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int ha=1000000007;
const int maxn=1000005;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
int main(){
    int n,P=0,p=1,now=1; scanf("%d",&n);
    for(int i=2;i<=n;i++,P=p,p=now) now=add(add(p,p),P);
    printf("%d\n",now);
    return 0;
}