【题解】ARC144D - AND OR Equation
给定 \(n, k\),求有多少种方案,使得 \(\forall 0 \le i \le 2^n - 1, 0\le f(i)\le K\),满足 \(f(x) + f(y) = f(x \operatorname{and} y) + f(x \operatorname{or}y)\)。
考虑 \(x = 2^a,y = 2^b,a\neq b\) 的情况,有 \(f(x+y) = f(x) + f(y) - f(0)\)。
因此我们可以直接归纳到任意情况,令 \(c = f(0), g(i) = f(2^i) - c\),那么有 \(f(s) = c + \sum\limits_{i\in s} g(i)\)。
所以任意一组 \(\{c, g(0),g(1),\cdots,g(n - 1)\}\) 对应一个 \(f\) 的方案。需要满足 \(0\le c\le k\),且选出若干个 \(g\) 的和满足 \(\in[-c,k - c]\)。
简单贪心以下,我们求出 $<0 $ 的 \(g\) 的和为 \(s^+\),其余的 \(g\) 的和为 \(s ^ -\),那么我们得到不等式 \(-s^- \le c \le k - s ^+\),同时一定有 \(-s^- \ge 0,k - s^+ \le k\),所以对于一个 \((s^-,s^+)\) 的方案,\(c\) 的有 \(\max(0, k - s^+ + s^- + 1)\) 种方案。
由于 \(\sum |g| = s^+ - s^-\),所以我们求 \(\sum (k - \sum|g| + 1)\),用组合意义,相当于捆绑求一组 \(g\) 和一个 \(\sum |g| \le a \le k + 1\) 的方案,可以用插板法。最后再固定每个 \(g\) 的符号,所以我们要枚举 \(g\) 中 \(0\) 的个数。
#define N 300005
LL n, k, m, u[N], fc[N], iv[N];
int C(int x,int y){return fc[x] * 1LL * iv[y] % P * iv[x - y] % P;}
int D(int x){return u[x] * 1LL * iv[x] % P;}
int main() {
read(n, k), m = n + 1;
fc[0] = 1; rp(i, m)fc[i] = fc[i - 1] * (LL)i % P;
iv[m] = Pow(fc[m], P - 2); pr(i, m)iv[i - 1] = iv[i] * (LL)i % P;
u[0] = 1; rp(i, m)u[i] = (k + 1 - i + 1) % P * u[i - 1] % P;
int ans = 0, w = 1;
rep(i, 0, n)ad(ans, w * 1LL * C(n, i) % P * D(i + 1) % P), ad(w, w);
cout << ans << endl;
return 0;
}