不知道怎么说这题,考场时完全没有想过生成函数,随便想想就有70+分了啊。
考虑d个中如果有k个是奇数,则
(
n
−
k
)
/
2
>
=
m
(n-k)/2>=m
(n−k)/2>=m
即
k
<
=
n
−
2
m
k<=n-2m
k<=n−2m,当然
k
<
=
D
k<=D
k<=D
设 f [ k ] f[k] f[k]表示k个奇数的方案。
考虑用生成函数强解:
f
[
k
]
=
C
D
k
∗
D
!
∗
(
e
x
−
e
−
x
2
)
k
∗
(
e
x
+
e
−
x
2
)
D
−
k
[
x
n
]
f[k]=C_{D}^k*D!*({e^x-e^{-x}\over2})^k*({e^x+e^{-x}\over2})^{D-k}[x^n]
f[k]=CDk∗D!∗(2ex−e−x)k∗(2ex+e−x)D−k[xn]
发现这个真的不会拆了,但是随便写写就有70分了。
不好拆的关键主要在于有两个东西,不妨容斥一下
g
[
k
]
g[k]
g[k]表示至少k个的方案
g
[
k
]
=
∑
i
=
k
D
C
i
k
∗
f
[
i
]
g[k]=\sum_{i=k}^DC_{i}^k*f[i]
g[k]=∑i=kDCik∗f[i]
f
[
k
]
=
∑
i
=
k
D
C
i
k
∗
g
[
i
]
∗
(
−
1
)
i
−
k
f[k]=\sum_{i=k}^DC_{i}^k*g[i]*(-1)^{i-k}
f[k]=∑i=kDCik∗g[i]∗(−1)i−k
g
[
k
]
=
C
D
k
∗
D
!
∗
e
D
−
k
∗
(
e
x
−
e
−
x
2
)
k
[
x
n
]
g[k]=C_{D}^k*D!*e^{D-k}*({e^x-e^{-x}\over2})^k[x^n]
g[k]=CDk∗D!∗eD−k∗(2ex−e−x)k[xn]
g
[
k
]
=
C
D
k
∗
D
!
∗
2
−
k
∗
e
(
D
−
k
)
x
∗
∑
i
=
0
k
(
−
1
)
i
∗
e
i
x
+
(
k
−
i
)
x
[
x
n
]
∗
C
k
i
g[k]=C_{D}^k*D!*2^{-k}*e^{(D-k)x}*\sum_{i=0}^k(-1)^i*e^{ix+(k-i)x}[x^n]*C_{k}^i
g[k]=CDk∗D!∗2−k∗e(D−k)x∗∑i=0k(−1)i∗eix+(k−i)x[xn]∗Cki
g
[
k
]
=
C
D
k
∗
D
!
∗
2
−
k
∗
∑
i
=
0
k
(
−
1
)
i
∗
e
i
x
+
(
k
−
i
)
x
+
(
D
−
k
)
x
[
x
n
]
∗
C
k
i
g[k]=C_{D}^k*D!*2^{-k}*\sum_{i=0}^k(-1)^i*e^{ix+(k-i)x+(D-k)x}[x^n]*C_{k}^i
g[k]=CDk∗D!∗2−k∗∑i=0k(−1)i∗eix+(k−i)x+(D−k)x[xn]∗Cki
g
[
k
]
=
C
D
k
∗
D
!
∗
2
−
k
∗
∑
i
=
0
k
(
−
1
)
i
∗
e
(
D
−
2
i
)
x
[
x
n
]
∗
C
k
i
g[k]=C_{D}^k*D!*2^{-k}*\sum_{i=0}^k(-1)^i*e^{(D-2i)x}[x^n]*C_{k}^i
g[k]=CDk∗D!∗2−k∗∑i=0k(−1)i∗e(D−2i)x[xn]∗Cki
g
[
k
]
=
C
D
k
∗
D
!
∗
2
−
k
∗
∑
i
=
0
k
(
−
1
)
i
∗
(
D
−
2
i
)
n
∗
C
k
i
g[k]=C_{D}^k*D!*2^{-k}*\sum_{i=0}^k(-1)^i*(D-2i)^n*C_{k}^i
g[k]=CDk∗D!∗2−k∗∑i=0k(−1)i∗(D−2i)n∗Cki
到这一步已经非常显然的可以 N T T NTT NTT优化了。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
#define ui unsigned int
using namespace std;
const int mo = 998244353;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const int N = 1e5 + 4;
ll a[N * 4], b[N * 4]; int r[N * 4];
void dft(ll *a, int n, int f) {
ff(i, 0, n) {
r[i] = r[i / 2] / 2 + (i & 1) * n / 2;
if(i < r[i]) swap(a[i], a[r[i]]);
}
for(int h = 1; h < n; h *= 2) {
ll wn = ksm(ksm(3, (mo - 1) / 2 / h), f == 1 ? 1 : mo - 2);
for(int j = 0; j < n; j += 2 * h) {
ll w = 1, b, *l = a + j, *r = a + j + h;
ff(i, 0, h) {
b = *r * w, *r = (*l - b) % mo, *l = (*l + b) % mo;
w = w * wn % mo, l ++, r ++;
}
}
}
if(f == -1) {
ll v = ksm(n, mo - 2);
ff(i, 0, n) a[i] = (a[i] + mo) * v % mo;
}
}
void fft(ll *a, ll *b, int n) {
dft(a, n, 1); dft(b, n, 1);
ff(i, 0, n) a[i] = a[i] * b[i] % mo;
dft(a, n, -1);
}
int n, n2, m;
ll fac[N], nf[N];
#define mem(a) memset(a, 0, sizeof a)
int main() {
scanf("%d %d %d", &n, &n2, &m);
fac[0] = 1; fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
nf[n] = ksm(fac[n], mo - 2); fd(i, n, 1) nf[i - 1] = nf[i] * i % mo;
int tp = 0; while(1 << ++ tp <= 2 * n);
fo(i, 0, n) {
a[i] = ksm(n - 2 * i, n2) * (i % 2 ? -1 : 1) * nf[i] % mo;
b[i] = nf[i];
}
fft(a, b, 1 << tp);
ff(i, n + 1, 1 << tp) a[i] = 0;
mem(b);
fo(i, 0, n) {
a[i] = a[i] * ksm((mo + 1) / 2, i) % mo * fac[n] % mo * nf[n - i] % mo * fac[i] % mo;
b[n - i] = nf[i] % mo * (i % 2 ? -1 : 1);
}
fft(a, b, 1 << tp);
fo(i, 0, n) a[i] = a[i + n] * nf[i] % mo;
ll ans = 0;
fo(i, 0, min(n2 - 2 * m, n)) ans += a[i];
pp("%lld\n", (ans % mo + mo) % mo);
}
1695

被折叠的 条评论
为什么被折叠?



