QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#178171 | #4380. Travel plan | jrjyy# | AC ✓ | 1305ms | 50880kb | C++20 | 6.3kb | 2023-09-13 18:56:28 | 2023-09-13 18:56:29 |
Judging History
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;
}
Details
Tip: Click on the bar to expand more detailed information
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