QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#659954#6623. Perfect MatchingstieguodundaeWA 16ms251996kbC++232.9kb2024-10-20 00:06:362024-10-20 00:06:36

Judging History

你现在查看的是最新测评结果

  • [2024-10-20 00:06:36]
  • 评测
  • 测评结果:WA
  • 用时:16ms
  • 内存:251996kb
  • [2024-10-20 00:06:36]
  • 提交

answer

#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
using namespace std;
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", print_args(__VA_ARGS__)
template <class... T>
void print_args(T... args) { ((cerr << args << ' '), ...) << '\n'; }
typedef long long ll;
const int mod = 998244353, inf = 1e9;
const int N = 4E3 + 5;
ll d[N]; // u点,选了j条边,第j条边选择, 匹配数
ll fac[N], infac[N];
vector<int> g[N];
ll power(ll a, int b, int p) {
    ll res = 1;
    for (; b; b /= 2, a = 1LL * a * a % p) {
        if (b % 2) res = 1LL * res * a % p;
    }
    return res;
}
void init_comb() {
    int len = N - 1;
    fac[0] = 1;
    for (int i = 1; i <= len; i++) fac[i] = 1LL * fac[i - 1] * i % mod;
    infac[len] = power(fac[len], mod - 2, mod);
    for (int i = len - 1; i >= 0; i--) infac[i] = 1LL * infac[i + 1] * (i + 1) % mod;
}
void init() {
    ll t = 1;
    for (int i = 0; i < N; i += 2) { //d[2i]
        d[i] = fac[i] * t % mod * infac[i / 2] % mod;
        t = t * infac[2] % mod;
    }
}
ll dp[N][N][2], siz[N];
void dfs(int u, int f) {
    dp[u][0][0] = 1;
    siz[u] = 1;
    for (auto v : g[u]) {
        if (v == f) continue;
        dfs(v, u);
        // 枚举u子树配对了多少对(<=siz[u]/2),v子树配对了多少对(siz[v]/2)
        for (int i = siz[u] / 2; ~i; i--) {
            for (int j = 0; j <= siz[v] / 2; j++) {
                if (j > 0) {
                    // u 子树合并 v 子树,u 没选
                    dp[u][i + j][0] += dp[u][i][0] * ((dp[v][j][0] + dp[v][j][1]) % mod) % mod;
                    dp[u][i + j][0] %= mod;
                    // u 已经在字数内被选
                    dp[u][i + j][1] += dp[u][i][1] * ((dp[v][j][0] + dp[v][j][1]) % mod) % mod;
                    dp[u][i + j][1] %= mod;
                }
                // u-v 选
                dp[u][i + j + 1][1] += dp[u][i][0] * dp[v][j][0] % mod;
                dp[u][i + j + 1][1] %= mod;
            }
        }
        siz[u] += siz[v];
    }
}
void solve() {
    int n;
    cin >> n;
    for (int i = 1; i < n * 2; i++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, 0);
    ll ans = 0;
    // 容斥原理 |A∪B∪C|,将每一棵树边看作一个元素(A,B,C),最后求的就是树边的贡献之和
    for (int i = 0, j = 1; i <= n; i++, j *= -1) { // 最少有几条树边参与(1~n)
        ll t = (dp[1][i][0] + dp[1][i][1]) % mod; // 贡献了几条树边(i条树边必须选择)
        ans += j * t % mod * d[2 * n - 2 * i] % mod;
        ans %= mod;
    }
    cout << ans << '\n';
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    init_comb();
    init();

    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3784kb

input:

2
1 2
1 3
3 4

output:

1

result:

ok 1 number(s): "1"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3716kb

input:

3
1 2
2 3
3 4
4 5
5 6

output:

5

result:

ok 1 number(s): "5"

Test #3:

score: 0
Accepted
time: 1ms
memory: 3840kb

input:

10
2 1
3 2
4 2
5 3
6 3
7 5
8 4
9 3
10 5
11 3
12 9
13 11
14 8
15 5
16 1
17 4
18 1
19 11
20 19

output:

223263378

result:

ok 1 number(s): "223263378"

Test #4:

score: 0
Accepted
time: 1ms
memory: 5796kb

input:

10
2 1
3 1
4 1
5 1
6 5
7 3
8 7
9 3
10 2
11 3
12 5
13 12
14 10
15 11
16 10
17 4
18 14
19 4
20 4

output:

225215244

result:

ok 1 number(s): "225215244"

Test #5:

score: 0
Accepted
time: 1ms
memory: 3836kb

input:

10
2 1
3 1
4 3
5 3
6 5
7 3
8 5
9 3
10 8
11 2
12 1
13 11
14 2
15 3
16 3
17 2
18 11
19 10
20 3

output:

210104685

result:

ok 1 number(s): "210104685"

Test #6:

score: 0
Accepted
time: 0ms
memory: 5752kb

input:

10
2 1
3 2
4 3
5 1
6 2
7 5
8 2
9 3
10 2
11 10
12 7
13 12
14 2
15 2
16 15
17 2
18 6
19 15
20 8

output:

211263144

result:

ok 1 number(s): "211263144"

Test #7:

score: 0
Accepted
time: 1ms
memory: 3840kb

input:

10
2 1
3 2
4 3
5 2
6 2
7 1
8 7
9 3
10 8
11 5
12 6
13 11
14 8
15 1
16 13
17 2
18 14
19 11
20 12

output:

226024809

result:

ok 1 number(s): "226024809"

Test #8:

score: -100
Wrong Answer
time: 16ms
memory: 251996kb

input:

1977
2 1
3 1
4 1
5 4
6 4
7 1
8 3
9 5
10 2
11 3
12 2
13 3
14 2
15 9
16 9
17 2
18 17
19 5
20 16
21 2
22 2
23 15
24 16
25 22
26 14
27 6
28 4
29 24
30 25
31 28
32 15
33 27
34 32
35 24
36 10
37 18
38 15
39 33
40 3
41 27
42 3
43 35
44 15
45 11
46 19
47 21
48 4
49 28
50 6
51 3
52 14
53 14
54 14
55 25
56 18...

output:

-660749750

result:

wrong answer 1st numbers differ - expected: '337494603', found: '-660749750'