結果
問題 | No.2616 中央番目の中央値 |
ユーザー |
|
提出日時 | 2024-01-26 23:13:21 |
言語 | C# (.NET 8.0.404) |
結果 |
AC
|
実行時間 | 1,768 ms / 2,000 ms |
コード長 | 8,283 bytes |
コンパイル時間 | 9,381 ms |
コンパイル使用メモリ | 167,136 KB |
実行使用メモリ | 242,108 KB |
最終ジャッジ日時 | 2024-09-28 09:02:37 |
合計ジャッジ時間 | 40,432 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 37 |
コンパイルメッセージ
復元対象のプロジェクトを決定しています... /home/judge/data/code/main.csproj を復元しました (97 ms)。 MSBuild のバージョン 17.9.6+a4ecab324 (.NET) main -> /home/judge/data/code/bin/Release/net8.0/main.dll main -> /home/judge/data/code/bin/Release/net8.0/publish/
ソースコード
namespace AtCoder;#nullable enableusing System.Numerics;using System.Text;readonly record struct ModInt :IEqualityOperators<ModInt, ModInt, bool>,IAdditiveIdentity<ModInt, ModInt>,IAdditionOperators<ModInt, ModInt, ModInt>,IUnaryNegationOperators<ModInt, ModInt>,ISubtractionOperators<ModInt, ModInt, ModInt>,IMultiplicativeIdentity<ModInt, ModInt>,IMultiplyOperators<ModInt, ModInt, ModInt>,IDivisionOperators<ModInt, ModInt, ModInt>{int V { get; init; }public const int Mod = 998244353;public ModInt(long value){var v = value % Mod;if (v < 0) v += Mod;V = (int)v;}ModInt(int value) { V = value; }public static implicit operator ModInt(long v) => new(v);public static implicit operator int(ModInt modInt) => modInt.V;public static ModInt operator +(ModInt a, ModInt b){var v = a.V + b.V;if (v >= Mod) v -= Mod;return new(v);}public static ModInt operator -(ModInt a) => new(a.V == 0 ? 0 : Mod - a.V);public static ModInt operator -(ModInt a, ModInt b){var v = a.V - b.V;if (v < 0) v += Mod;return new(v);}public static ModInt operator *(ModInt a, ModInt b) => new((int)((long)a.V * b.V % Mod));public static ModInt operator /(ModInt a, ModInt b){if (b == 0) throw new DivideByZeroException();var (d, x, _) = ExtendedGcd(b.V, Mod);if (d > 1) throw new DivideByZeroException();return x * a.V;}public ModInt Power(long p){if (p < 0) return (MultiplicativeIdentity / V).Power(-p);long res = 1;long k = V;while (p > 0){if ((p & 1) > 0) res = res * k % Mod;k = k * k % Mod;p >>= 1;}return res;}static (long d, long x, long y) ExtendedGcd(long a, long b){if (b == 0) return (a, 1, 0);var (d, x, y) = ExtendedGcd(b, a % b);return (d, y, x - a / b * y);}public static ModInt AdditiveIdentity => new(0);public static ModInt MultiplicativeIdentity => new(1);public override string ToString() => V.ToString();}static class FactorialExtensions{static ModInt[] fac = Array.Empty<ModInt>();static ModInt[] inv = Array.Empty<ModInt>();const uint Capacity = 1 << 24;static void Resize(uint n){if (n < fac.Length) return;var s = 1;while (s < n && s < Capacity) s <<= 1;fac = new ModInt[s + 1];fac[0] = 1;for (var i = 1; i <= s; i++) fac[i] = fac[i - 1] * i;inv = new ModInt[s + 1];inv[s] = fac[0] / fac[s];for (var i = s; i > 0; i--) inv[i - 1] = inv[i] * i;}public static ModInt Factorial(this int n) { Resize((uint)Math.Abs(n)); return n < 0 ? inv[-n] : fac[n]; }public static ModInt C(this int n, int r){if (r < 0 || n < r) return 0;if (n <= Capacity) return Factorial(n) * Factorial(r - n) * Factorial(-r);if (n - r < r) return C(n, n - r);var res = fac[0];for (var i = n; i > n - r; i--) res *= i;return res * Factorial(-r);}public static ModInt P(this int n, int r) => C(n, r) * Factorial(-r);public static ModInt H(this int n, int r) => C(n + r - 1, r);}abstract class SegmentTree<TMonoid>{public interface IOperator{TMonoid IdentityElement { get; }TMonoid Operation(TMonoid x, TMonoid y);}public interface IBinarySearchOperator { bool F(TMonoid value); }public class Body<TOperator> where TOperator : struct, IOperator{public int BaseSize { get; init; }protected int Height { get; init; }protected TOperator Op { get; init; }protected TMonoid[] Values { get; init; }public Body(TMonoid[] initial, TOperator op = default){Op = op;(BaseSize, Height) = (1, 0);while (BaseSize < initial.Length) (BaseSize, Height) = (BaseSize << 1, Height + 1);var size = BaseSize << 1;Values = new TMonoid[size];for (var i = 0; i < size; i++) Values[i] = op.IdentityElement;for (var i = 0; i < initial.Length; i++) Values[i + BaseSize] = initial[i];for (var i = BaseSize - 1; i > 0; i--) Update(i);}public TMonoid Product(int l, int r){(l, r) = (l + BaseSize, r + BaseSize);var (resL, resR) = (Op.IdentityElement, Op.IdentityElement);while (l < r){if ((l & 1) == 1) resL = Op.Operation(resL, Values[l++]);if ((r & 1) == 1) resR = Op.Operation(Values[--r], resR);(l, r) = (l >> 1, r >> 1);}return Op.Operation(resL, resR);}public void Set(int index, TMonoid value){var j = index + BaseSize;Values[j] = value;for (var i = 1; i <= Height; i++) Update(j >> i);}// the result might be greater than npublic int MinIndex<TMinIndexOperator>(TMinIndexOperator op = default) where TMinIndexOperator : struct, IBinarySearchOperator{if (!op.F(Values[1])) return BaseSize + 1;var product = Op.IdentityElement;var (res, w, i) = (0, BaseSize, 1);while (w > 0){var p = Op.Operation(product, Values[i]);if (!op.F(p)){res += w;i++;product = p;}w >>= 1;i <<= 1;}return res + 1;}protected void Update(int k) { Values[k] = Op.Operation(Values[k << 1], Values[(k << 1) + 1]); }}}struct Op : SegmentTree<int>.IOperator{public int IdentityElement => 0;public int Operation(int x, int y) => x + y;}static class Extensions{public static T[] Repeat<T>(this int time, Func<T> F) => Enumerable.Range(0, time).Select(_ => F()).ToArray();}class AtCoder{object? Solve(){var n = Int();var q = new int[n];for (var i = 0; i < n; i++){var x = Int() - 1;q[x] = i;}var t0 = new SegmentTree<int>.Body<Op>(n.Repeat(() => 0));var t1 = new SegmentTree<int>.Body<Op>(n.Repeat(() => 1));ModInt ans = 0;for (var i = 0; i < n; i++){var k = q[i];ModInt bns = 1;for (var j = 0; j < 2; j++){var x = t0.Product(0, k);var y = t1.Product(k + 1, n);var s = x + y;bns *= s.Factorial() / (x.Factorial() * y.Factorial());(t0, t1) = (t1, t0);}ans += bns;t0.Set(k, 1);t1.Set(k, 0);}return ans;}public static void Main() => new AtCoder().Run();public void Run(){var res = Solve();if (res != null){if (res is bool yes) res = yes ? "Yes" : "No";sw.WriteLine(res);}sw.Flush();}string[] input = Array.Empty<string>();int iter = 0;readonly StreamWriter sw = new(Console.OpenStandardOutput()) { AutoFlush = false };#pragma warning disable IDE0051string String(){while (iter >= input.Length) (input, iter) = (Console.ReadLine()!.Split(' '), 0);return input[iter++];}T Input<T>() where T : IParsable<T> => T.Parse(String(), null);int Int() => Input<int>();void Out(object? x, string? separator = null){separator ??= Environment.NewLine;if (x is System.Collections.IEnumerable obj and not string){var firstLine = true;foreach (var item in obj){if (!firstLine) sw.Write(separator);firstLine = false;sw.Write(item);}}else sw.Write(x);sw.WriteLine();}#pragma warning restore IDE0051}