1.
一句话题意:构造一个长度为n的数组,a[1,n],范围为[1,m].其中偶数出现的次数必须是偶数次。
2.解析:母函数计数问题。还是很常规的用法,母函数写一下。这里我们是首先考虑无限长的时候,然后再单独的看n的系数即可。假设在[1,m]中有t个偶数,那么就有m-t个奇数。
然后泰勒级数求和一下:
然后化简一下,把括号二项式展开:
这个时候,把e^x做一下泰勒展开,其实可以这样考虑,首先把i看作常数,然后会有t个含有e^x的式子,对于每个式子,我们考虑这个式子的第n项,然后把这些系数加起来就是答案。最
展开可得:
那么对于第n项的系数就是:
到这里,这个题就做完了,其实难度很低。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int N = 200010;
ll fac[N];
ll inv[N];
ll qpow(ll a, ll b)
{
ll res = 1;
while (b)
{
if (b & 1)res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init()
{
fac[0] = 1;
for (int i = 1; i < N; i++)
fac[i] = fac[i - 1] * i % mod;
inv[N - 1] = qpow(fac[N - 1], mod - 2);
for (int i = N - 2; i >= 0; i--)
inv[i] = inv[i + 1] * (i + 1) % mod;
}
int main()
{
init();
int T;
scanf("%d", &T);
while (T--)
{
ll n, m;
scanf("%lld%lld", &n, &m);
int t = m / 2;
ll ans = 0;
for (int i = 0; i <= t; i++)
{
ans = (ans + fac[t] * inv[i] % mod * inv[t - i] % mod * qpow((m - i * 2), n) % mod) % mod;
}
ll inv2 = qpow(qpow(2, t), mod - 2);
printf("%lld\n", ans * inv2 % mod);
}
return 0;
}