The Preliminary Contest for ICPC Asia Shanghai 2019 E. Counting Sequences II(生成函数\母函数)

题意

给你 n n n, m m m,让你求长度为 n n n的序列 a 1 , a 2 , a 3 , ⋯ a n a_1,a_2,a_3,\cdots a_n a1,a2,a3,an序列的个数,序列有如下要求

  • 1 ≤ a i ≤ m 1\le a_i \le m 1aim对于所有 1 ≤ i ≤ n 1\le i\le n 1in
  • 对于所有偶数,他的出现次数也是偶数

思路

将题意转换一下就是求多重集的排列问题,相当于给你 m m m个数字给 n n n个格子填数字,其中要求偶数的数字填偶数个。这样就是经典的生成函数求解多重集排列问题了
一共有 m m m个数字那么其中偶数的个数为 ⌊ m 2 ⌋ \left \lfloor \frac{m}{2} \right \rfloor 2m,而奇数个为 m − ⌊ m 2 ⌋ m-\left \lfloor \frac{m}{2} \right \rfloor m2m
t = ⌊ m 2 ⌋ t=\left \lfloor \frac{m}{2} \right \rfloor t=2m
G e ( x ) = ( 1 + x 2 2 ! + x 4 4 ! + ⋯   ) t ( 1 + x + x 2 2 ! + ⋯   ) m − t G_e(x)=(1+\frac{x^2}{2!}+\frac{x^4}{4!}+\cdots)^t(1+x+\frac{x^2}{2!}+\cdots)^{m-t} Ge(x)=(1+2!x2+4!x4+)t(1+x+2!x2+)mt
G e ( x ) = ( 1 2 ( e x + e − x ) ) t e ( m − t ) x G_e(x)=(\frac{1}{2}(e^x+e^{-x}))^te^{(m-t)x} Ge(x)=(21(ex+ex))te(mt)x
G e ( x ) = 1 2 t e ( m − t ) x ∑ i = 0 t C t i e ( t − i ) x e − i x G_e(x)=\frac{1}{2^t}e^{(m-t)x}\sum_{i=0}^{t}C_{t}^ie^{(t-i)x}e^{-ix} Ge(x)=2t1e(mt)xi=0tCtie(ti)xeix
G e ( x ) = 1 2 t ∑ i = 0 t C t i e ( m − 2 i ) x G_e(x)=\frac{1}{2^t}\sum_{i=0}^{t}C_{t}^ie^{(m-2i)x} Ge(x)=2t1i=0tCtie(m2i)x
G e ( x ) = ∑ n = 0 ∞ ∑ i = 0 t C t i ( m − 2 i ) n 2 t x n n ! G_e(x)=\sum_{n=0}^{\infty}\frac{\sum_{i=0}^{t}C_{t}^i(m-2i)^n}{2^t}\frac{x^n}{n!} Ge(x)=n=02ti=0tCti(m2i)nn!xn
所以答案就是
a n s = ∑ i = 0 t C t i ( m − 2 i ) n 2 t ans=\frac{\sum_{i=0}^{t}C_{t}^i(m-2i)^n}{2^t} ans=2ti=0tCti(m2i)n
a n s = C t 0 m n + C t 1 ( m − 2 ) n + C t 2 ( m − 4 ) n + ⋯ + C t t ( m − 2 t ) n 2 t ans=\frac{C_{t}^{0}m^n+C_{t}^{1}(m-2)^n+C_{t}^{2}(m-4)^n+\cdots+C_{t}^{t}(m-2t)^n}{2^t} ans=2tCt0mn+Ct1(m2)n+Ct2(m4)n++Ctt(m2t)n
m m m 2 e 5 2e^5 2e5,所以组合数要用预处理逆元来求解

#include 
using namespace std;
const int mod=1e9+7;
const int N=200005;
long long fac[N];
long long inv[N];
long long quickmod(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b%2==1)
            ans=ans*a%mod;
        b=b/2;
        a=a*a%mod;
    }
    return ans;
}
int main()
{
    fac[0]=1;
    for(int i=1;i=0;i--)
        inv[i]=inv[i+1]*(i+1)%mod;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,m;
        scanf("%lld%lld",&n,&m);
        int mm=m/2;
        long long ans=0;
        for(int i=0;i<=mm;i++)
        {
            ans=(ans+fac[mm]*inv[i]%mod*inv[mm-i]%mod*quickmod((m-i*2),n)%mod)%mod;
        }
        long long inv2=quickmod(quickmod(2,mm),mod-2);
        printf("%lld\n",ans*inv2%mod);
    }
    return 0;
}


你可能感兴趣的:(母函数)