ATR102E Stop. Otherwise... [容斥]

第一道容斥

\(ans[i] = \sum_{j = 0}^{min(cnt, n / 2)} (-1)^j \tbinom{cnt}{j} \tbinom{n - 2*j + k - 1}{k - 1}\)

i 为 [2, 2k]
cnt是满足x, y小于等于k 且 x + y = i 的对的种类数
后面那个组合数是除了j对 数剩下的数的取值
即\(\sum_{t = 1}^{k} X_t = n - 2j\)
\(X_t\)指t的出现次数

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 4005;
const double eps = 1e-9;
const long long P = 998244353;
int n, k;
long long jie[N], jv[N], inv[N], tot[N];
long long C(long long x, long long y){
    return jie[x] * jv[x - y] % P * jv[y] % P;
}

int main() {
    scanf("%d%d", &k, &n);
    jie[0] = inv[0] = jv[0] = jie[1] = inv[1] = jv[1] = 1;
    for(int i = 2; i <= n + k; ++i){
        jie[i] = jie[i - 1] * i % P; 
        inv[i] = (P - P / i) * inv[P % i] % P; 
        jv[i] = jv[i - 1] * inv[i] % P;
    }
    for(int i = 1; i <= k; ++i) ++tot[i + 1], --tot[i + k + 1];
    for(int i = 1; i <= k + k; ++i) tot[i] += tot[i - 1]; //存在另一个数y满足x + y = i的x有多少个 
    for(int i = 2; i <= k + k; ++i){
        long long cnt = ((tot[i] + 1) >> 1), ans = 0;
        for(int j = 0, d = 1; j <= cnt && j + j <= n; ++j, d = P - d){
            ans = (ans + 1ll * d * C(cnt, j) % P * C(n - (j << 1) + k - 1, k - 1) % P) % P;
            //       d = (-1)^j          选择哪几对            剩下的数取哪些 
        }
        printf("%lld\n", ans);
    }
    return 0;    
}
上一篇:[SCOI2003]字符串折叠


下一篇:【P4302 [SCOI2003]字符串折叠】题解