生成函数(线性递推关系,生成函数概念与公式推导,暴力计算)四千字详细解析,附例题

目录

形式幂级数

形式幂级数的逆元

常见的逆元

例题一

例题二

例题三

指数生成函数

常见公式转化

例题四


形式幂级数

多项式与形式幂级数

多项式

 A(x) =\sum_{i=0}^{n} a_{i}x^{i}

形式幂级数 

  A(x)=\sum_{i\geq 0}^{}a_{i}x^{i}

  • 加减法

  A(x) \pm B(x) =\sum_{i\geq 0} (a_{i}\pm b_{i}) x^{i}

  • 乘法

A(x)B(x) =\sum_{k\geq 0}^{} (\sum_{i+j=k}^{}ai*bj) x^{k}

 记号

A(x) 的x^n项的系数  [x^n]A(X)

f(x)= 1+2x+3x^2

[x^2]f(X)=3

常生成函数

一个数列{an}对应的常生成函数

A(x) = a0 +a1x+ a2x^{^{2}} +.....+anx^{n}

 A(x)=1+x^{2}+x^{4}+....

B(x)=1+x^{3}+x^{^{6}}+.....

C(x)=1+x+x^{2}+x^{3}+x^{4}+x^{5}

S(x)=A(x)B(x)C(x)=1+x+2*2^{x}+...

O(n^2)循环计算即可

其中幂级数的系数为其选择的方案数,x的指数代表选了几个

形式幂级数的逆元

形式幂级数A(x)的逆元   A(x)B(x)=1

逆元存在的条件 [x^0]A(x)!=0    常数项不为0

常见的逆元

A(x) =1+x+x^{2}+...

B(x)=1-x

1/(1-x)=A(x)

 A(x)=1+ax+a^{2}x^{2}+....

 B(x)=1-ax

1/(1-ax)=A(x)

A(x)=\binom{0+k-1}{0}*1 +\binom{1+k-1}{1}*x+\binom{2+k-1}{2}*x^{2}+....

B(x)=(1-x)^{k}

 1/(1-x)^{k}=A(X)=\sum_{i>=x}^{} \binom{i+k-1}{i}x^{i}

例题一

背包

等比数列进行求和  1+x+x^2+...x^n  = 1(1-q^n+1)/(1-x) =  (1-x^n+1)/(1-x)  

0<x<1时,n->无穷,等比数列求和结果为  首/(1-q)

条件1  1+x

条件2 1+x+x^2    1-x^3/(1-x)

条件3 1+x+x^2+x^3     1-x^4/(1-x)

条件4 1+x^2+x^4+......   1/(1-x^2)

条件5 x+x^3+x^5+......   x/(1-x^2)

条件6 1+x^4+x^8+......    1/(1-x^4)

条件7 1+x

条件8 1+x^3+x^6+......  1/(1-x^3)

相乘化简后

g(x)=x/(1-x)^4=

分母进行展开 ,根据第三类总结得

1/(1-x)^{4}= \binom{0+4-1}{0}1+\binom{1+4-1}{1}x+\binom{2+4-1}{2}x^{2}+..+.\binom{n+4-1}{n}x^{n}

g(x)=\binom{0+4-1}{0}x+\binom{1+4-1}{1}x^{2}+\binom{2+4-1}{2}x^{3}+..+.\binom{n+4-1}{n}x^{n+1}

每一项x的指数代表选择几个,其系数代表有几种选法

代入n求得n个的选法即可,注意逆元处理

#include <bits/stdc++.h>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdio>
# include<set>
#include <iostream>
using namespace std;
typedef  long long int   ll;
# define mod  1000000007

ll get(ll base,ll pow)
{
    ll ans=1;

    while(pow)
    {
        if(pow&1)
        {
            ans=ans*base%mod;
        }

        base=base*base%mod;


        pow>>=1;
    }


    return ans;

}
int main ()
{


    ll n;

    cin>>n;

    n%=mod;

    ll ans1=(n+2)%mod*(n+1)%mod*(n)%mod;

    ans1*=get(6,mod-2);

    cout<<ans1%mod;


    return 0;

}

例题二

​​​​​​Devu and Flowers

Fi(x)=1+x+x^{2}+...xfi = (1-xfi+1)/(1-x)

F(x)=\prod_{i=1}^{n} Fi(x) =\prod_{i=1}^{n}(1-x^{fi+1}) /(1-x)^{n}

对于   1/(1-x)n这一项,利用第三种逆元来处理最好,其中第x^k项的系数为 \binom{k+n-1}{k}

之后  F(x)=A(x)/(1-x)^{n}  

而[x^k]  F(x)=  \sum_{i=0}^{k}[x^i]A(x) * [x^^{k-i}]B(x)

[x^k-i]B(x)  =\binom{k-i+n-1}{k-i}=(k-i+n-1)! /(k-i)! (n-1)!

#include <bits/stdc++.h>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdio>
# include<set>
#include <iostream>
using namespace std;
typedef  __int128  ll;
# define mod  1000000007

ll a[30];
ll inv[30];
ll jc[30];

map<ll,ll>mp;

int n;


__int128 read(){
    __int128 x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)&&ch!='-')ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
void print(__int128 x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)print(x/10);
    putchar(x%10+'0');
}

void dfs(int u,ll x,int cnt)
{
    if(u==n+1)
    {
        if(cnt%2==0)
            mp[x]++;
        else
            mp[x]--;

        return ;

    }

    dfs(u+1,x,cnt);

    dfs(u+1,x+a[u]+1,cnt+1);

}

ll qpow(ll base,ll pow)
{
    ll ans=1;

    while(pow)
    {
        if(pow&1)
            ans=ans*base%mod;

        pow>>=1;

        base=base*base%mod;

    }

    return ans;

}

ll C(ll aa,ll bb)
{
    ll ans=inv[aa];

    for(ll i=1;i<=n-1;i++)
    {
        ans=((bb+i)%mod*ans)%mod;

    }

    return ans;

}


int main ()
{

n=read();


ll s;

s=read();



     for(int i=1;i<=n;i++)
     {
        a[i]=read();


     }

     jc[0]=1;

     for(int i=1;i<=22;i++)
     {
         jc[i]=jc[i-1]*i%mod;

     }

     inv[22]=qpow(jc[22],mod-2);


     for(int i=21;i>=0;i--)
     {
         inv[i]=inv[i+1]*(i+1)%mod;

     }

     dfs(1,0,0);

     ll ans=0;

     for(auto it:mp)
     {
         if(it.first>s)
            break;

         ans+=(it.second%mod+mod)%mod*C(n-1,s-it.first);


         
         ans%=mod;
         



     }

    print(ans);


    return 0;

}

例题三

[CEOI2004] Sweets

Fi(x)=1+x+x^2+...x^{m_{i}} = 1-x^{m_{i}+1} /1- x

F(x)=F1(x)F2(x)F3(x)...Fn(x)=\prod_{i=1}^{n} (1-x^(mi+1)) /(1-x)^n

求出a<=x<=b之间的和

令A(x)= \prod_{i=1}^{n} (1-x^(mi+1))

B(x)=1/(1-x)^n

x=k时,其系数为    \sum_{i=0}^{n} [x^i]A(x) *[x^(k-i)]B(x)

其中第一项用dfs处理,第二项   固定公式 \binom{k-i+n-1}{k-i}

 而对于a<=k<=b

得到公式\sum_{k=a}^{b} \sum_{i=0}^{n} [x^i]A(x) *[x^(k-i)]B(x)

[x^k]A(x) \sum_{i=a-k}^{b-k} \binom{i+n-1}{i}     其中k满足 a-k>=0   b-k>=0,即k<=b即可

右边一项利用组合式公式  \binom{n}{m} =\binom{n}{m-1} + \binom{n-1}{m-1}

最后化为   \binom{b-k+n}{b-k} - \binom{n+a-k-1}{a-k-1}  两者不过10次循环,容易求解

然而很caodan的是,我们的模数不是质数,意味着我们无法通过逆元来求解,这里一个技巧是,我们求出分母,将模数乘上分母,对分子取模之后再除以分母即可。

k<=a+1时  后者是一定能出来值的,最小是1

一旦k>a+1 k<=b时, 前者一定能出来值,而后者的值应该被赋值为0

# include<iostream>

# include<map>
# include<iomanip>
# include<algorithm>
# include<vector>
# include<set>
# define mod 2004
# include<queue>

using namespace std;

typedef long long int ll;

ll fac[20];
ll m[20];
ll n,a,b;
map<ll,ll>mp;

void dfs(ll step, ll x,ll cnt)
{
    if(step==n+1)
    {
        if(cnt%2)
            mp[x]--;
        else
            mp[x]++;

            return  ;


    }

    dfs(step+1,x+m[step],cnt+1);

    dfs(step+1,x,cnt);

}

ll getc(ll x)
{
    if(x<0)
    return  0;


    ll ans=1;

    for(int i=1;i<=n;i++)
    {
        ans=(ans*(x+i))%(mod*fac[n]);

    }


    ans/=fac[n];

    ans%=mod;

    return ans;

}
int main ()
{


   fac[0]=1;

   for(int i=1;i<=10;i++)
   {
       fac[i]=fac[i-1]*i;

   }

   cin>>n>>a>>b;

   for(int i=1;i<=n;i++)
   {
       cin>>m[i];

       m[i]++;

   }

   dfs(1,0,0);

   ll ans=0;

   for(auto it:mp)
   {
       ll k=it.first;

       ll se=it.second;


       ll c1=getc(b-k);

       ll c2=getc(a-k-1);


       ll temp=((se*(c1-c2)%mod+mod))%mod;

       ans=(ans+temp)%mod;




   }

   cout<<ans;



    return 0;

}

 递推关系

斐波那契数列 a0=0,a1=1,an=an-1+an-2  ,求其常生成函数

A(x) =x+x^2A(x)+xA(x)

A(x) = x/(1-x-x^2)

卡特兰数

生成函数     C(x) = (1-\sqrt{1-4x} )/2x

通项公式 Cn=1/(n+1) \binom{2n}{n}

指数生成函数

A(x) =\sum_{n>=0}^{} an * x^{n} / n!

 特别的,当an=1时, A(x)= e^x 

k个位置摆在面前,首先相同物体之间并没有什么差别,但k个位置中多少个是1,多少个是2是具有差别的,故应该先从k个位置组合一下i个位置填1的方案数

Ck =\sum_{i=0}^{k} \binom{k}{i} ai * bk-i

 Ck =\sum_{i=0}^{k} k!/ i! (k-i)! ai *bk-i

Ck/ k! =\sum_{i=0}^{k} ai /i! * bk-i / (k-i)!

再按照幂级数展开计算即可。

ans=    6!  [x^6]     ( 1+x+x^2/2!  )^4

指数函数定理如下

关键词  排成一列的方案数

常见公式转化

e^x= 1+x+x^2/2! +....=\sum_{n>=0}^{} x^n /n!

e^{ax} = 1+ax+a^2x^2/2! +.....= \sum_{n>=0}^{} anx^n/n!

 (ex+e^{-x})/2=1+x^2/2! +x^4/4!+.... =\sum_{i=0,2|i}^{n} ai x^i/i!

例题四

Blocks

进行一系列推导

F(x) =(e^x+e^{-x}) ^2 e^{2x} /4=(e^{4x} +2e^{2x} +1 )/4

前两项均可以展开,而后面的1其实就是一个常数,对于指数大于等于1的x并没有影响

对其进行展开 

\sum_{n>=0}^{} ( 4^n x^n /n! +2* 2^n x^n /n! )/4 + (1/4

ans=   n!【x^n] f(x)  = (4^n+2*2^n)/4

值得注意的是最终幂级数x^n项的系数其实相当于[x^n]  f(x)/n! ,但是方案数确实  [x^n] f(x)也就是an

# include<iostream>

# include<map>
# include<iomanip>
# include<algorithm>
# include<vector>
# include<set>
# define mod 10007
# include<queue>

using namespace std;

typedef long long int ll;


ll quick(ll base, ll pow)
{
    ll ans=1;

    while(pow)
    {
        if(pow&1)
            ans=ans*base%mod;

        pow>>=1;

        base=base*base%mod;

    }

    return ans;

}

int main ()
{


     int t;

     cin>>t;

     while(t--)
     {
         ll n;

         cin>>n;


         cout<<(quick(4ll,n-1)+quick(2ll,n-1))%mod<<endl;

     }





    return 0;

}

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinsanma and Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值