結果
| 問題 |
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();
}