結果
| 問題 |
No.3250 最小公倍数
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2025-08-29 23:01:17 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,159 bytes |
| コンパイル時間 | 3,807 ms |
| コンパイル使用メモリ | 300,728 KB |
| 実行使用メモリ | 20,848 KB |
| 最終ジャッジ日時 | 2025-10-16 16:32:48 |
| 合計ジャッジ時間 | 11,169 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | TLE * 1 -- * 21 |
ソースコード
/*
==================== ORIGINAL PYTHON (do not remove) ====================
MOD = 998244353
from collections import defaultdict
from math import isqrt
def sieve(n: int):
"""エラトステネスの篩(O(n log log n))"""
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, isqrt(n) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return [i for i in range(n + 1) if is_prime[i]]
def factorize(n: int, primes=None):
"""素因数分解(O(√n))"""
factorized = defaultdict(int)
it = range(2, isqrt(n) + 1) if primes is None else primes
for i in it:
while n % i == 0:
factorized[i] += 1
n //= i
if n > 1:
factorized[n] += 1
return factorized
N = int(input())
A = list(map(int, input().split()))
tree = [[] for _ in range(N)]
for _ in range(N - 1):
u, v = map(int, input().split())
tree[u - 1].append(v - 1)
tree[v - 1].append(u - 1)
primes = sieve(10**6)
lcm = [factorize(A[i], primes) for i in range(N)]
def dfs(v, p):
for u in tree[v]:
if u == p:
continue
dfs(u, v)
for k, val in lcm[u].items():
lcm[v][k] = max(lcm[v][k], val)
dfs(0, -1)
for i in range(N):
ans = 1
for k, v in lcm[i].items():
ans = (ans * pow(k, v, MOD)) % MOD
print(ans)
========================================================================
*/
#include <bits/stdc++.h>
using namespace std;
static const long long MOD = 998244353LL;
vector<int> sieve(int n) {
// エラトステネスの篩(O(n log log n))
vector<char> is_prime(n + 1, true);
if (n >= 0) is_prime[0] = false;
if (n >= 1) is_prime[1] = false;
int lim = static_cast<int>(sqrt((long double)n));
for (int i = 2; i <= lim; ++i) {
if (is_prime[i]) {
long long start = 1LL * i * i;
for (long long j = start; j <= n; j += i) is_prime[(int)j] = false;
}
}
vector<int> primes;
for (int i = 2; i <= n; ++i) if (is_prime[i]) primes.push_back(i);
return primes;
}
// 素因数分解:Python実装の「primes をそのまま全て舐める」挙動を厳密に踏襲
unordered_map<long long, int> factorize_with_primes(long long n, const vector<int>& primes) {
unordered_map<long long, int> res;
for (int p : primes) {
while (n % p == 0) {
res[p] += 1;
n /= p;
}
}
if (n > 1) res[n] += 1;
return res;
}
long long mod_pow(long long a, long long e, long long mod) {
long long r = 1 % mod;
a %= mod;
while (e > 0) {
if (e & 1) r = (__int128)r * a % mod;
a = (__int128)a * a % mod;
e >>= 1;
}
return r;
}
int N;
vector<long long> A;
vector<vector<int>> tree;
vector<unordered_map<long long, int>> lcm_exp;
void dfs(int v, int p) {
for (int u : tree[v]) {
if (u == p) continue;
dfs(u, v);
for (const auto& kv : lcm_exp[u]) {
long long k = kv.first;
int val = kv.second;
auto it = lcm_exp[v].find(k);
if (it == lcm_exp[v].end()) {
lcm_exp[v][k] = val;
} else if (it->second < val) {
it->second = val;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
A.resize(N);
for (int i = 0; i < N; ++i) cin >> A[i];
tree.assign(N, {});
for (int i = 0; i < N - 1; ++i) {
int u, v;
cin >> u >> v;
--u; --v;
tree[u].push_back(v);
tree[v].push_back(u);
}
vector<int> primes = sieve(1'000'000);
lcm_exp.resize(N);
for (int i = 0; i < N; ++i) {
lcm_exp[i] = factorize_with_primes(A[i], primes);
}
dfs(0, -1);
for (int i = 0; i < N; ++i) {
long long ans = 1;
for (const auto& kv : lcm_exp[i]) {
long long k = kv.first;
int e = kv.second;
ans = (ans * mod_pow(k, e, MOD)) % MOD;
}
cout << ans << '\n';
}
return 0;
}