結果
問題 |
No.3249 AND
|
ユーザー |
|
提出日時 | 2025-08-30 01:13:23 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 6,393 bytes |
コンパイル時間 | 4,148 ms |
コンパイル使用メモリ | 268,528 KB |
実行使用メモリ | 42,356 KB |
最終ジャッジ日時 | 2025-08-30 01:13:34 |
合計ジャッジ時間 | 8,684 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | RE * 1 |
other | WA * 1 RE * 20 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; #define rep(i, s, t) for (ll i = s; i < (ll)(t); i++) #define all(x) begin(x), end(x) template <class T> bool chmin(T& x, T y) { return x > y ? (x = y, true) : false; } template <class T> bool chmax(T& x, T y) { return x < y ? (x = y, true) : false; } struct io_setup { io_setup() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); } } io_setup; // https://nyaannyaan.github.io/library/tree/dsu-on-tree.hpp.html #line 2 "tree/dsu-on-tree.hpp" #line 2 "graph/graph-template.hpp" template <typename T> struct edge { int src, to; T cost; edge(int _to, T _cost) : src(-1), to(_to), cost(_cost) { } edge(int _src, int _to, T _cost) : src(_src), to(_to), cost(_cost) { } edge& operator=(const int& x) { to = x; return *this; } operator int() const { return to; } }; template <typename T> using Edges = vector<edge<T>>; template <typename T> using WeightedGraph = vector<Edges<T>>; using UnweightedGraph = vector<vector<int>>; // Input of (Unweighted) Graph UnweightedGraph graph(int N, int M = -1, bool is_directed = false, bool is_1origin = true) { UnweightedGraph g(N); if (M == -1) M = N - 1; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; if (is_1origin) x--, y--; g[x].push_back(y); if (!is_directed) g[y].push_back(x); } return g; } // Input of Weighted Graph template <typename T> WeightedGraph<T> wgraph(int N, int M = -1, bool is_directed = false, bool is_1origin = true) { WeightedGraph<T> g(N); if (M == -1) M = N - 1; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; cin >> c; if (is_1origin) x--, y--; g[x].emplace_back(x, y, c); if (!is_directed) g[y].emplace_back(y, x, c); } return g; } // Input of Edges template <typename T> Edges<T> esgraph([[maybe_unused]] int N, int M, int is_weighted = true, bool is_1origin = true) { Edges<T> es; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; if (is_weighted) cin >> c; else c = 1; if (is_1origin) x--, y--; es.emplace_back(x, y, c); } return es; } // Input of Adjacency Matrix template <typename T> vector<vector<T>> adjgraph(int N, int M, T INF, int is_weighted = true, bool is_directed = false, bool is_1origin = true) { vector<vector<T>> d(N, vector<T>(N, INF)); for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; if (is_weighted) cin >> c; else c = 1; if (is_1origin) x--, y--; d[x][y] = c; if (!is_directed) d[y][x] = c; } return d; } /** * @brief グラフテンプレート * @docs docs/graph/graph-template.md */ #line 6 "tree/dsu-on-tree.hpp" template <typename G> struct DSUonTree { private: G& g; int N; vector<int> sub_sz, euler, down, up; int idx_; int root; int dfs1(int cur, int par = -1) { sub_sz[cur] = 1; if ((int)g[cur].size() >= 2 and g[cur][0] == par) { swap(g[cur][0], g[cur][1]); } for (auto& dst : g[cur]) { if (dst == par) continue; sub_sz[cur] += dfs1(dst, cur); if (sub_sz[dst] > sub_sz[g[cur][0]]) swap(dst, g[cur][0]); } return sub_sz[cur]; } void dfs2(int cur, int par = -1) { euler[idx_] = cur; down[cur] = idx_++; for (auto& dst : g[cur]) { if (dst == par) continue; dfs2(dst, cur); } up[cur] = idx_; } public: DSUonTree(G& _g, int _root = 0) : g(_g), N(_g.size()), sub_sz(_g.size()), euler(_g.size()), down(_g.size()), up(_g.size()), idx_(0), root(_root) { dfs1(root); dfs2(root); } int idx(int u) const { return down[u]; } template <typename UPDATE, typename QUERY, typename CLEAR, typename RESET> void run(UPDATE& update, QUERY& query, CLEAR& clear, RESET& reset) { auto dsu = [&](auto rc, int cur, int par = -1, bool keep = false) -> void { for (int i = 1; i < (int)g[cur].size(); i++) if (g[cur][i] != par) rc(rc, g[cur][i], cur, false); if (sub_sz[cur] != 1) rc(rc, g[cur][0], cur, true); if (sub_sz[cur] != 1) for (int i = up[g[cur][0]]; i < up[cur]; i++) update(euler[i]); update(cur); query(cur); if (!keep) { for (int i = down[cur]; i < up[cur]; i++) clear(euler[i]); reset(); } return; }; dsu(dsu, root); } }; /** * @brief DSU on Tree(Guni) * @docs docs/tree/dsu-on-tree.md */ namespace cho { std::vector<int> prime_table(int n) { std::vector<int> p(n + 1, -1); for (int i = 2; i * i <= n; i++) { if (p[i] != -1) continue; for (int j = i * i; j <= n; j += i) { p[j] = i; } } return p; } std::map<int, int> table_factor(int n) { const static std::vector<int> table = prime_table(1e7); assert(n <= 1e7); std::map<int, int> res; while (n > 1) { if (table[n] == -1) { res[n]++; break; } res[table[n]]++; n /= table[n]; } return res; } } // namespace cho #include <atcoder/all> using mint = atcoder::modint998244353; void solve() { int n; cin >> n; vector<int> a(n); rep(i, 0, n) cin >> a[i]; auto g = graph(n); vector<vector<array<int, 2>>> dda(n); rep(i, 0, n) { auto mp = cho::table_factor(a[i]); vector<array<int, 2>> vp; dda[i].reserve(mp.size()); for (auto [k, x] : mp) dda[i].push_back({k, x}); } map<int, int> mp; mint ans = 1; vector<mint> vans(n); // reflect data of node i auto update = [&](int i) { for (auto [val, x] : dda[i]) { ans *= mint(val).pow(x - mp[val]); mp[val] = x; } }; // answer queries of subtree i auto query = [&](int i) { vans[i] = ans; }; // below two function are called if all data must be deleted // delete data of node i (if necesarry) auto clear = [&](int i) { // for (auto [val, x] : dda[i]) { // auto itr = mp.find(val); // if (itr->second.size() == 1) { // mp.erase(itr); // ans /= mint(val).pow(x); // } else { // auto itr2 = itr->second.find(x); // if (next(itr2) == itr->second.end()) { // itr->second.erase(itr2); // ans /= mint(val).pow(x - *itr->second.rbegin()); // } else { // itr->second.erase(itr2); // } // } // } }; // delete data related to all (if necesarry) auto reset = [&]() { mp.clear(); ans = 1; }; DSUonTree<decltype(g)> dsu(g, 0); dsu.run(update, query, clear, reset); rep(i, 0, n) cout << vans[i].val() << "\n"; } int main() { int t = 1; // cin >> t; while (t--) solve(); }