結果
問題 |
No.3167 [Cherry 7th Tune C] Cut in Queue
|
ユーザー |
|
提出日時 | 2025-06-02 15:35:44 |
言語 | C# (.NET 8.0.404) |
結果 |
AC
|
実行時間 | 2,042 ms / 2,500 ms |
コード長 | 7,962 bytes |
コンパイル時間 | 8,179 ms |
コンパイル使用メモリ | 172,392 KB |
実行使用メモリ | 344,668 KB |
最終ジャッジ日時 | 2025-06-02 15:36:42 |
合計ジャッジ時間 | 52,774 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 43 |
コンパイルメッセージ
復元対象のプロジェクトを決定しています... /home/judge/data/code/main.csproj を復元しました (99 ミリ秒)。 main -> /home/judge/data/code/bin/Release/net8.0/main.dll main -> /home/judge/data/code/bin/Release/net8.0/publish/
ソースコード
#nullable enable using System.Numerics; void Run() { var n = Int(); var a = new FlexibleArray<int>(n.Repeat(Int)); var ans = new List<int>(); var l = n; var q = Int(); for (var i = 0; i < q; i++) { var t = Int(); if (t == 1) { var k = Int(); if (k == 0) a.InsertAt(++l, a.Count); else { var j = a.FindIndex(k)!.Value; a.InsertAt(++l, j); } } else if (t == 2) a.DeleteAt(0); else { var k = Int() - 1; ans.Add(a.At(k)); } } Out(ans); } #region var _io_ = new AtCoderIO(){ Backend = new() }; Run(); _io_.Backend.Flush(); string String() => _io_.Next(); int Int() => int.Parse(String()); void Out(object? x, string? sep = null) => _io_.Out(x, sep); class AtCoderIO { public required StandardIOBackend Backend { get; init; } ReadOnlyMemory<string> _input = Array.Empty<string>(); int _iter = 0; public string Next() { while (_iter >= _input.Length) (_input, _iter) = (Backend.ReadLine().Trim().Split(' '), 0); return _input.Span[_iter++]; } public void Out(object? x, string? separator = null) { if (x == null) return; separator ??= Environment.NewLine; if (x is System.Collections.IEnumerable a and not string) { var objects = a.Cast<object>(); if (separator == Environment.NewLine && !objects.Any()) return; x = string.Join(separator, objects); } Backend.WriteLine(x); } } class StandardIOBackend { readonly StreamReader _sr = new(Console.OpenStandardInput()); readonly StreamWriter _sw = new(Console.OpenStandardOutput()) { AutoFlush = false }; public string ReadLine() => _sr.ReadLine()!; public void WriteLine(object? value) => _sw.WriteLine(value); public void Flush() => _sw.Flush(); } #endregion static class Extensions { public static T[] Repeat<T>(this int time, Func<T> F) => Enumerable.Range(0, time).Select(_ => F()).ToArray(); } class ScapegoatTree<T> { protected class Node { public required T Data { get; set; } public Node? P { get; set; } public Node? L { get; set; } public Node? R { get; set; } public int Size { get; set; } = 1; public Node? this[bool i] { get => i ? R : L; set { if (i) R = value; else L = value; } } } protected readonly double _sizeFactor = 2.0 / 3; protected readonly double _heightFactor = -1.0 / Math.Log(2.0 / 3); protected Node? Root { get; set; } protected int _maxCount = 0; public T At(int index) => At(Root, index).Data; protected static Node At(Node? node, int index) { while (node != null) { var ls = Size(node.L); if (index == ls) return node; var right = index > ls; if (right) index -= ls + 1; node = node[right]; } throw new IndexOutOfRangeException(); } protected Node? DeleteAtInternal(int index) { Node? deleted = null; var root = Root = DeleteAt(Root, null, ref deleted, index); if (root != null && Count < _sizeFactor * _maxCount) { Root = Rebuild(root, null); _maxCount = Count; } return deleted; } Node? DeleteAt(Node? node, Node? prev, ref Node? deleted, int index) { if (node == null) return null; var ls = Size(node.L); if (ls == index) { deleted = node; node = Merge(node.L, node.R, prev); if (node != null) Update(node); return node; } var right = index > ls; var li = right ? index - 1 - ls : index; node[right] = DeleteAt(node[right], node, ref deleted, li); Update(node); return node; } Node? Merge(Node? l, Node? r, Node? prev) { if (l == null) { if (r != null) r.P = prev; return r; } if (r == null) { l.P = prev; return l; } if (l.Size < r.Size) { r.L = Merge(l, r.L, r); r.P = prev; Update(r); return r; } else { l.R = Merge(l.R, r, l); l.P = prev; Update(l); return l; } } protected static Node Rebuild(Node node, Node? prev) { var len = node.Size; var nodes = new Node[len].AsSpan(); var index = 0; Traverse(node, nodes, ref index); return Rebuild(nodes, 0, len, prev); } static void Traverse(Node? node, Span<Node> nodes, ref int i) { if (node == null) return; Traverse(node.L, nodes, ref i); nodes[i++] = node; Traverse(node.R, nodes, ref i); } protected static Node Rebuild(Span<Node> nodes, int l, int r, Node? prev) { var m = (l + r) >> 1; var res = nodes[m]; res.P = prev; if (l < m) res.L = Rebuild(nodes, l, m, res); else res.L = null; if (m + 1 < r) res.R = Rebuild(nodes, m + 1, r, res); else res.R = null; Update(res); return res; } public int Count => Size(Root); protected static void Update(Node node) { node.Size = 1 + Size(node.L) + Size(node.R); } protected static int Size(Node? node) => node?.Size ?? 0; } class FlexibleArray<T> : ScapegoatTree<T> where T : notnull { readonly Dictionary<T, HashSet<Node>> _reversed = new(); public FlexibleArray(IReadOnlyList<T> values) { var span = values.Select(e => new Node(){ Data = e }).ToArray().AsSpan(); for (var i = 0; i < span.Length; i++) { var node = span[i]; if (_reversed.TryGetValue(node.Data, out var s)) s.Add(node); else _reversed[node.Data] = new(){ node }; } Root = Rebuild(span, 0, span.Length, null); } public T this[int index] { get => At(Root, index).Data; set { InsertAt(value, index); } } public int? FindIndex(T value) { if (_reversed.TryGetValue(value, out var nodes) && nodes.Count > 0) { var node = nodes.First(); var res = Size(node.L); while (true) { var p = node.P; if (p == null) break; if (p.R == node) res += Size(p.L) + 1; node = p; } return res; } return null; } public void InsertAt(T value, int index) { var balanced = true; var inserted = new Node(){ Data = value }; Root = InsertAt(Root, null, inserted, 0, ref balanced, index); _maxCount = Math.Max(_maxCount, Size(Root)); if (_reversed.TryGetValue(value, out var s)) s.Add(inserted); else _reversed[value] = new(){ inserted }; } public void DeleteAt(int index) { var deleted = DeleteAtInternal(index); if (deleted != null && _reversed.TryGetValue(deleted.Data, out var s)) s.Remove(deleted); } Node InsertAt(Node? node, Node? prev, Node inserted, int depth, ref bool balanced, int index) { if (node == null) { inserted.P = prev; balanced = depth <= _heightFactor * Math.Log2(_maxCount + 2); return inserted; } var ls = Size(node.L); var right = index > ls; var li = right ? index - 1 - ls : index; node[right] = InsertAt(node[right], node, inserted, depth + 1, ref balanced, li); Update(node); if (balanced || Size(node[right]) <= _sizeFactor * node.Size) return node; balanced = true; return Rebuild(node, prev); } }