题意
给你 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 1≤ai≤m对于所有 1 ≤ i ≤ n 1\le i\le n 1≤i≤n
- 对于所有偶数,他的出现次数也是偶数
思路
将题意转换一下就是求多重集的排列问题,相当于给你
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
m−⌊2m⌋
令
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+⋯)m−t
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+e−x))te(m−t)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(m−t)xi=0∑tCtie(t−i)xe−ix
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=0∑tCtie(m−2i)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=0∑∞2t∑i=0tCti(m−2i)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=2t∑i=0tCti(m−2i)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(m−2)n+Ct2(m−4)n+⋯+Ctt(m−2t)n
m
m
m才
2
e
5
2e^5
2e5,所以组合数要用预处理逆元来求解
#include <bits/stdc++.h>
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<N;i++)
fac[i]=fac[i-1]*i%mod;
inv[N-1]=quickmod(fac[N-1],mod-2);
for(int i=N-2;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;
}