QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#592479#7895. Graph Partitioning 2ucup-team3519RE 0ms3800kbC++174.6kb2024-09-26 22:51:572024-09-26 22:51:58

Judging History

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

  • [2024-09-26 22:51:58]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3800kb
  • [2024-09-26 22:51:57]
  • 提交

answer

#include <bits/stdc++.h>

template <int m>
class ModInt {
    int raw_;

public:
    using mint = ModInt;
    using i64 = int64_t;

    ModInt() : raw_(0) {}
    ModInt(const auto &v) : raw_(v % m) {}

    int value() const {
        return (raw_ + m) % m;
    }

    mint &operator+=(const mint &rhs) {
        raw_ = (raw_ + rhs.raw_) % m;
        return *this;
    }
    mint &operator-=(const mint &rhs) {
        raw_ = (raw_ - rhs.raw_) % m;
        return *this;
    }
    mint &operator*=(const mint &rhs) {
        raw_ = (i64)raw_ * rhs.raw_ % m;
        return *this;
    }

    friend mint operator+(const mint &lhs, const mint &rhs) {
        return mint{lhs} += rhs;
    }
    friend mint operator-(const mint &lhs, const mint &rhs) {
        return mint{lhs} -= rhs;
    }
    friend mint operator*(const mint &lhs, const mint &rhs) {
        return mint{lhs} *= rhs;
    }
};

using mint = ModInt<998244353>;

std::vector<mint> conv(const std::vector<mint> &f, const std::vector<mint> &g,
                       int n) {
    if (f.empty() || g.empty()) {
        return {};
    }
    std::vector<mint> res(std::min<int>(n, f.size() + g.size() - 1));
    for (int i = 0; i < f.size(); ++i) {
        if (f[i].value() == 0) {
            continue;
        }
        for (int j = 0; j < g.size() && i + j < res.size(); ++j) {
            res[i + j] += f[i] * g[j];
        }
    }
    while (!res.empty() && res.back().value() == 0) {
        res.pop_back();
    }
    return res;
}

void small_k(int n, int k, const std::vector<std::vector<int>> &adj) {
    std::vector<std::vector<mint>> dp(n + 1);

    auto dfs = [&](auto self, int node, int fa) -> void {
        dp[node] = std::vector<mint>{0, 1};
        for (int to : adj[node]) {
            if (to == fa) {
                continue;
            }
            self(self, to, node);
            dp[node] = conv(dp[node], dp[to], k + 2);
        }
        if (k < dp[node].size()) {
            dp[node][0] += dp[node][k];
        }
        if (k + 1 < dp[node].size()) {
            dp[node][0] += dp[node][k + 1];
        }
    };
    dfs(dfs, 1, 0);

    if (0 < dp[1].size()) {
        std::cout << dp[1][0].value() << '\n';
    } else {
        std::cout << "0\n";
    }
}

void great_k(int n, int k, const std::vector<std::vector<int>> &adj) {
    auto [quot, rem] = div(n, k);
    if (rem > quot) {
        std::cout << "0\n";
        return;
    }

    std::vector<int> sz(n + 1);
    std::vector<std::vector<mint>> dp(n + 1);
    std::vector<mint> g(n + 1); // root in a (k + 1) chunk
    auto dfs = [&](auto self, int node, int fa) -> void {
        sz[node] = 1;
        dp[node] = std::vector<mint>{1};
        for (int to : adj[node]) {
            if (to == fa) {
                continue;
            }
            self(self, to, node);

            std::vector<mint> F(dp[node].size() + dp[to].size() - 1);
            mint ng = 0;
            for (int x = 0; x < dp[node].size(); ++x) {
                const int cx = (sz[node] + k - x - 1) % k + 1;
                for (int y = 0; y < dp[to].size(); ++y) {
                    const int cy = (sz[to] + k - y - 1) % k + 1;
                    if (cx + cy == k + 1) {
                        ng += dp[node][x] * dp[to][y];
                    } else if (cx + cy <= k) {
                        F[x + y] += dp[node][x] * dp[to][y];
                    }
                }
                F[x] += dp[node][x] * g[to];
            }
            for (int y = 0; y < dp[to].size(); ++y) {
                const int cy = (sz[to] + k - y - 1) % k + 1;
                if (cy == k) {
                    ng += g[node] * dp[to][y];
                }
            }
            ng += g[node] * g[to];

            while (!F.empty() && F.back().value() == 0) {
                F.pop_back();
            }
            sz[node] += sz[to];
            dp[node].swap(F);
            g[node] = ng;
        }
    };
    dfs(dfs, 1, 0);

    mint ans = g[1];
    if (rem < dp[1].size()) {
        ans += dp[1][rem];
    }
    std::cout << ans.value() << '\n';
}

void solve() {
    int n, k;
    std::cin >> n >> k;

    std::vector<std::vector<int>> adj(n + 1);
    for (int i = 1; i < n; ++i) {
        int u, v;
        std::cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    if (k + 1 < 350) {
        small_k(n, k, adj);
    } else {
        great_k(n, k, adj);
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t;
    std::cin >> t;

    while (t--) {
        solve();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3800kb

input:

2
8 2
1 2
3 1
4 6
3 5
2 4
8 5
5 7
4 3
1 2
1 3
2 4

output:

2
1

result:

ok 2 lines

Test #2:

score: -100
Runtime Error

input:

5550
13 4
10 3
9 1
10 8
3 11
8 5
10 7
9 6
13 5
9 7
2 7
5 12
4 8
8 2
4 1
3 4
7 8
2 5
6 7
4 8
2 3
11 1
11 10
1 4
9 10
8 4
3 6
5 7
6 1
10 2
11 7
11 1
17 2
14 16
13 15
17 3
15 11
1 6
13 2
13 17
4 8
14 10
8 14
14 5
9 12
14 2
12 17
17 6
15 7
14 6
2 14
2 13
2 4
8 4
3 11
7 3
14 1
11 9
13 3
5 10
6 8
3 10
14 ...

output:

0
3
112
0
1
0
1
0
0
0
1
0
1
0
0
1
0
140
0
0
0
814
1
6
1
1
2
2
0
612
0
1
0
0
0
1
1
0
0
121
4536
0
0
1718
0
0
1
0
444
1
1908
1813
3
74
0
1
0
46
0
0
0
0
0
0
0
0
0
1
0
1
1
1
239
0
0
0
1
0
0
0
1
0
1
0
0
1
1
0
0
0
1
0
0
0
48
0
2
0
0
0
1
364
0
206
0
0
76
0
1
0
0
2
0
1
2
0
0
1
0
0
4
0
1
1
0
0
1
1
1
0
0
1
1
...

result: