QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#178171#4380. Travel planjrjyy#AC ✓1305ms50880kbC++206.3kb2023-09-13 18:56:282023-09-13 18:56:29

Judging History

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

  • [2023-09-13 18:56:29]
  • 评测
  • 测评结果:AC
  • 用时:1305ms
  • 内存:50880kb
  • [2023-09-13 18:56:28]
  • 提交

answer

#include <bits/stdc++.h>

using i64 = long long;

template <typename T> constexpr T power(T a, i64 b) {
    T c{1}; for (; b; b /= 2, a *= a) if (b & 1) c *= a;
    return c;
}
template <int P> struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(i64 x_) : x{norm(x_ % getMod())} {}
    static int Mod;
    constexpr static int getMod() { return P > 0 ? P : Mod; }
    constexpr static void setMod(int Mod_) { Mod = Mod_; }
    constexpr int up(int x) const {
        if (x < 0) x += getMod();
        return x;
    }
    constexpr int down(int x) const {
        if (x >= getMod()) x -= getMod();
        return x;
    }
    constexpr int norm(int x) const {
        return up(down(x));
    }
    constexpr int val() const { return x; }
    explicit constexpr operator int() const { return x; }
    constexpr MInt operator-() const {
        MInt res; res.x = norm(getMod() - x); return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &operator+=(MInt rhs) & { return x = down(x + rhs.x), *this; }
    constexpr MInt &operator-=(MInt rhs) & { return x = up(x - rhs.x), *this; }
    constexpr MInt &operator*=(MInt rhs) & { return x = 1ll * x * rhs.x % getMod(), *this; }
    constexpr MInt &operator/=(MInt rhs) & { return *this *= rhs.inv(); }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) { return lhs += rhs; }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) { return lhs -= rhs; }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) { return lhs *= rhs; }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) { return lhs /= rhs; }
    friend constexpr bool operator==(MInt lhs, MInt rhs) { return lhs.val() == rhs.val(); }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) { return lhs.val() != rhs.val(); }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        i64 x = 0; is >> x, a = MInt(x); return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
};

template <int P> int MInt<P>::Mod = P;
template <> int MInt<0>::Mod = 998244353;
template <int V, int P> constexpr MInt<P> CInv = MInt<P>(V).inv();

constexpr int P = 998244353;
using Z = MInt<P>;

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

    std::vector<std::tuple<int, int, int>> edges;
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        std::cin >> u >> v >> w;
        --u, --v;
        edges.emplace_back(u, v, w);
    }

    std::vector<std::vector<int>> bel(l + 1);
    for (int i = 0; i < m; ++i) {
        auto [u, v, w] = edges[i];
        for (int j = 1; j * j <= w; ++j) {
            if (w % j == 0) {
                bel[j].push_back(i);
                if (j * j != w) {
                    bel[w / j].push_back(i);
                }
            }
        }
    }

    std::vector<Z> ans(l + 1);
    std::vector<int> s;
    std::vector<std::vector<int>> adj(n), g(2 * n);
    std::vector<int> dfn(n), low(n), stk;
    std::vector<Z> f(2 * n);
    for (int x = 1; x <= l; ++x) {
        for (auto i : bel[x]) {
            auto [u, v, w] = edges[i];
            s.push_back(u);
            s.push_back(v);
            adj[u].push_back(v);
            adj[v].push_back(u);
        }

        std::sort(s.begin(), s.end());
        s.erase(std::unique(s.begin(), s.end()), s.end());

        for (auto u : s) {
            dfn[u] = low[u] = -1;
        }
        stk.clear();
        int cur = 0, cnt = 0;
        auto dfs = [&](auto self, int u) -> void {
            dfn[u] = low[u] = cur++;
            stk.push_back(u);
            for (auto v : adj[u]) {
                if (dfn[v] == -1) {
                    self(self, v);
                    low[u] = std::min(low[u], low[v]);
                    if (dfn[u] == low[v]) {
                        if (stk.back() == v) {
                            g[u].push_back(v);
                            stk.pop_back();
                        } else {
                            g[cnt + n].clear();
                            for (int x = -1; x != v; stk.pop_back()) {
                                x = stk.back();
                                g[cnt + n].push_back(x);
                            }
                            g[u].push_back(cnt + n);
                            ++cnt;
                        }
                    }
                } else {
                    low[u] = std::min(low[u], dfn[v]);
                }
            }
        };
        Z res = 0;
        auto dfs2 = [&](auto self, int u) -> void {
            f[u] = 0;
            Z sum = 0;
            for (auto v : g[u]) {
                self(self, v);
                if (u < n) {
                    res += 2 * f[v];
                }
                sum -= f[v] * f[v];
                f[u] += f[v];
            }
            sum += f[u] * f[u];
            res += sum * (1 + (u >= n));
            f[u] = (f[u] + (u < n)) * (1 + (u >= n));
        };
        for (auto u : s) {
            if (dfn[u] == -1) {
                dfs(dfs, u);
                dfs2(dfs2, u);
            }
        }
        ans[x] = res;
        
        for (auto u : s) {
            adj[u].clear();
            g[u].clear();
        }
        s.clear();
    }

    std::vector<int> pri, mu(l + 1);
    std::vector<bool> vis(l + 1);
    mu[1] = 1;
    for (int i = 2; i <= l; ++i) {
        if (!vis[i]) {
            pri.push_back(i);
            mu[i] = -1;
        }
        for (auto p : pri) {
            if (i * p > l) {
                break;
            }
            vis[i * p] = true;
            if (i % p == 0) {
                mu[i * p] = 0;
                break;
            } else {
                mu[i * p] = -mu[i];
            }
        }
    }

    int sum = 0;
    for (int i = 1; i <= l; ++i) {
        for (int j = 2 * i; j <= l; j += i) {
            ans[i] += mu[j / i] * ans[j];
        }
        sum ^= (ans[i] / 2).val();
    }

    std::cout << sum << "\n";
}

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

    int t;
    std::cin >> t;

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

    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 1305ms
memory: 50880kb

input:

405
3 3 6
1 2 6
2 3 4
3 1 5
5 4 10
1 2 10
1 3 1
2 4 8
4 5 9
100000 133392 100000
1 2 38759
1 3 63879
3 4 70473
1 5 79849
1 6 70562
5 7 83128
3 8 89713
4 9 6190
4 10 44171
7 11 99719
5 12 18707
1 13 33509
3 14 96110
11 15 84651
4 16 17844
3 17 64945
5 18 82684
9 19 94007
16 20 54506
11 21 10076
4 22 ...

output:

2
6
67078240
27003457
803251146
603512033
295921
64049237
209445
16863362
557344
176564099
933414
150267177
188786
226369182
148817
903133337
314734
69853467
162763
299319857
114659
836342484
146530
958360597
136066
983603446
157007
997887399
289109
178307076
262539
783549705
106788
19406148
73855
7...

result:

ok 405 lines