結果
問題 |
No.3250 最小公倍数
|
ユーザー |
|
提出日時 | 2025-08-29 23:17:20 |
言語 | C# (.NET 8.0.404) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,567 bytes |
コンパイル時間 | 11,639 ms |
コンパイル使用メモリ | 171,124 KB |
実行使用メモリ | 150,656 KB |
最終ジャッジ日時 | 2025-08-29 23:18:11 |
合計ジャッジ時間 | 40,387 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 3 WA * 14 TLE * 2 -- * 2 |
コンパイルメッセージ
復元対象のプロジェクトを決定しています... /home/judge/data/code/main.csproj を復元しました (116 ミリ秒)。 main -> /home/judge/data/code/bin/Release/net8.0/main.dll main -> /home/judge/data/code/bin/Release/net8.0/publish/
ソースコード
#nullable enable #region var _input = Array.Empty<string>(); var _iter = 0; string String() { while (_iter >= _input.Length) (_input, _iter) = (Console.ReadLine()!.Trim().Split(' '), 0); return _input[_iter++]; } T I<T>() where T : IParsable<T> => T.Parse(String(), null); #endregion T[] Range<T>(int n, Func<T> F) => Enumerable.Range(0, n).Select(_ => F()).ToArray(); var n = I<int>(); var az = Range(n, I<int>); var g = Range(n, () => new List<int>()); for (var i = 1; i < n; i++) { var u = I<int>() - 1; var v = I<int>() - 1; g[u].Add(v); g[v].Add(u); } const int Mod = 998244353; var max = az.Max(); var primes = new Prime(max).Primes; var kl = 0; while (kl < primes.Length && primes[kl] * primes[kl] <= max) kl++; var ptz = Range(kl, () => new List<long>()); for (var i = 0; i < kl; i++) { var pt = ptz[i]; var p = primes[i]; var last = 1L; while (last <= max) { pt.Add(last); last *= p; } } var ans = new long[n]; ans.AsSpan().Fill(1); int[] S(int v, int prev, ReadOnlySpan<int> primes) { var res = new int[kl]; var a = az[v]; for (var i = 0; i < kl; i++) { var p = primes[i]; while (a % p == 0) { a /= p; res[i]++; } } az[v] = a; var adjz = g[v]; foreach (var next in adjz) if (next != prev) { var nl = S(next, v, primes); for (var i = 0; i < kl; i++) res[i] = Math.Max(res[i], nl[i]); } for (var i = 0; i < kl; i++) ans[v] = ans[v] * ptz[i][res[i]] % Mod; return res; } S(0, -1, primes); var revz = new Dictionary<int, int>(); for (var i = kl; i < primes.Length; i++) revz[primes[i]] = i; var invz = new long[primes.Length].AsSpan(); for (var i = kl; i < primes.Length; i++) { var p = primes[i]; var power = Mod - 2; var v = 1L; var t = (long)p; while (power > 0) { if ((power & 1) != 0) v = v * t % Mod; t = t * t % Mod; power >>= 1; } invz[i] = v; } (IntegerContainer, long) T(int v, int prev, Span<long> invz) { var rs = new IntegerContainer(80000); var rv = 1L; var a = az[v]; if (a > 1) { rv = a; rs.Add(revz[a]); } var adjz = g[v]; foreach (var next in adjz) if (next != prev) { var (ns, nv) = T(next, v, invz); if (ns.values.Count > rs.values.Count) (rs, rv, ns, nv) = (ns, nv, rs, rv); rv = rv * nv % Mod; foreach (var i in ns.values) { if (rs.Contains(i)) rv = rv * invz[i] % Mod; else rs.Add(i); } } ans[v] = ans[v] * rv % Mod; return (rs, rv); } T(0, -1, invz); Console.WriteLine(string.Join(Environment.NewLine, ans)); struct IntegerContainer { public IntegerContainer(int max) { _max = max; } readonly int _max; public readonly List<int> values = new(); HashSet<int> _set = new(); ulong[]? _bits = null; public readonly bool Contains(int value) { var bits = _bits; if (bits != null) { var bit = bits[value >> 6]; var f = bit & (ulong)(value & 63); return f > 0; } return _set.Contains(value); } public void Add(int value) { if (!Contains(value)) return; values.Add(value); if (_set.Count == 64) { _set = new(); _bits = new ulong[1 + _max >> 6]; foreach (var v in _set) AddBits(_bits!, v); } var bits = _bits; if (bits == null) _set.Add(value); else AddBits(bits, value); } readonly void AddBits(ulong[] bits, int value) { var i = value & 63; bits[value >> 6] |= 1UL << i; } } class Prime { readonly ReadOnlyMemory<int> _sieve; readonly ReadOnlyMemory<int> _primes; public ReadOnlySpan<int> Sieve => _sieve.Span; public ReadOnlySpan<int> Primes => _primes.Span; public Prime(int n) { if (n <= 3) n = 3; var sieve = new int[n + 1]; var (d, i) = (2, 5); var primes = new List<int>(){ 2, 3 }; var span = sieve.AsSpan(); span[1] = 1; for (var j = 2; j <= n; j += 2) span[j] = 2; for (var j = 3; j <= n; j += 3) span[j] = 3; while (i <= n) { if (span[i] == 0) { primes.Add(i); for (var j = i; j <= n; j += i) span[j] = i; } i += d; d ^= 6; } _sieve = sieve; _primes = primes.ToArray(); } }