namespace test { internal class Program { static void Main(string[] args) { cin = new input(); mod = new mod(998244353); toolbox = new toolbox(); Priority_Queue = new Priority_Queue(true); var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false }; Console.SetOut(sw); toolbox.StartTimer(); int q=cin.intreed(); int k=cin.intreed(); var Query=new List<(int qtype,long val)>(); var set=new HashSet(); while(q-->0) { int mode=cin.intreed(); if(mode==1) { var val=cin.longreed(); Query.Add((1,val)); set.Add(val); } else { Query.Add((2,-1)); } } var comp=new Compress(set); var tree=new BinaryTrie32(); foreach(var i in Query) { if(i.qtype==1) { tree.Insert(comp.raw2key[i.val]); } else if(tree.Size >= k) { var val=tree[k];//これは圧縮されてる System.Console.WriteLine(comp[val]); tree.Erase(val); } else System.Console.WriteLine(-1); } toolbox.PrintElapsedTime(); Console.Out.Flush(); } static input cin; static mod mod; static toolbox toolbox; static Priority_Queue Priority_Queue; } public class ImplicitTreap { //1-indexです!!!!!! private class node { public long val;//これは中身だよ 二分木のとしてのキーではない public long QueryVal;//クエリ用の値 区間最小とか総和とか public long lazy_val;//遅延伝搬用の値 public bool lazy_flg;//遅延するものがあるのか public node left;//小さい public node right;//大きい public int cnt;//部分木の大きさ public int priority;//優先度 public bool rev;// 反転フラグ public node(long val, int priority, node left = null, node right = null) { this.val = val; this.priority = priority; this.left = left; this.right = right; } public long update() { //部分木の大きさを最新にする cnt = 1; if (left != null) cnt += left.cnt; if (right != null) cnt += right.cnt; return cnt; } //ここはやりたいことによって変える public void update_QueryVal() { //子から情報を吸い上げて親を最新の状態にする QueryVal = val; if (left != null) QueryVal += left.QueryVal; if (right != null) QueryVal += right.QueryVal; } //これもやりたいことによって変える public void Evaluate() { //自分自身に遅延評価を適用し、子はQueryValだけ更新し、それ以上の更新は子がEvaluateされた時にする if (lazy_flg) { if (left != null) { left.QueryVal = lazy_val * left.cnt; left.lazy_val = lazy_val; left.lazy_flg = true; } if (right != null) { right.QueryVal = lazy_val * right.cnt; right.lazy_val = lazy_val; right.lazy_flg = true; } val = lazy_val; lazy_val = 0; lazy_flg = false; } if (rev) { // 子を左右反転 var tmp = left; left = right; right = tmp; // 子に反転フラグを伝播(XOR) if (left != null) left.rev = !left.rev; if (right != null) right.rev = !right.rev; rev = false; } //自分を最新にする update_me(); } public void update_me() { update(); update_QueryVal(); } } private node root; private Random rand; public ImplicitTreap(int seed = 998244353) { root = null; rand = new Random(seed); } //内部向け //indexがkey未満のノードとkey以上のノードに分割する private void Split(node t, int key, out node left, out node right) { if (t == null) { left = null; right = null; return; } t.Evaluate(); int implicit_key = (t.left != null ? t.left.cnt : 0) + 1; if (key <= implicit_key) { //key以上なので、今回のノードと右側部分木は右に行く Split(t.left, key, out left, out t.left); right = t; } else { //key未満なので、今回のノードと右側部分木は右に行く Split(t.right, key - implicit_key, out t.right, out right); left = t; } t.update_me(); } //左と右を合体した新たな木(t)を作る private void Marge(ref node t, node left, node right) { if (left != null) left.Evaluate(); if (right != null) right.Evaluate(); if (left == null || right == null) { t = left ?? right; } else if (left.priority > right.priority) { //leftの方が優先度高い Marge(ref left.right, left.right, right); t = left; } else { //rightの方が優先度高い Marge(ref right.left, left, right.left); t = right; } if (t != null) t.update_me(); } //index=keyをitemに置き換える private void Insert(ref node t, int key, node item) { Split(t, key, out node t1, out node t2);// t1: [0,key) t2:[key,n) Marge(ref t1, t1, item);// t1: [0,key) + item Marge(ref t, t1, t2);// t: [0,key) + item + [key,n) } private void Erase(ref node t, int key) { Split(t, key + 1, out node t1, out node t2);// t1: [0,key+1) t2:[key+1,n) Split(t1, key, out t1, out node t3);// t1: [0,key) t3:[key,key+1) Marge(ref t, t1, t2);// t: [0,key) + [key+1,n) } //index=keyの要素を取得 private long Get(node t, int k) { if (t == null || k < 1 || k > t.cnt) throw new ArgumentOutOfRangeException(nameof(k)); t.Evaluate(); int leftCount = t.left != null ? t.left.cnt : 0; if (k <= leftCount) { return Get(t.left, k); } else if (k == leftCount + 1) { return t.val; } else { return Get(t.right, k - leftCount - 1); } } // --- クエリ [l, r) を計算する --- // 【内部ワーカー】木の根が変わる可能性があるので ref node で受けて、最後に必ず復元して t に戻す。 private long GetQueryVal(ref node t, int l, int r) { if (t == null || l >= r) return 0; // root を (=l) に分割 Split(t, l, out var t1, out var t2); // (>=l) を (=r-l) に分割 ⇒ 真ん中が [l, r) Split(t2, r - l + 1, out var t3, out var t4); long ans = t3?.QueryVal ?? 0; // 復元(順番厳守) node back = null; Marge(ref back, t3, t4); // back = (>=l) Marge(ref t, t1, back); // t を元に戻す return ans; } // 【ラッパ】node を受け取り、呼び出し側の木構造は変えない版。 // 参照をローカル変数に受けて ref でワーカーを呼ぶことで、見かけ上は非破壊になる。 private long GetQueryVal(node x, int l, int r) { return GetQueryVal(ref x, l, r); } // [l, r)に作用 private void RangeUpdate(ref node t, int l, int r, long val) { if (t == null || l >= r) return; // ① (< l) と (>= l) に分割 Split(t, l, out var A, out var BR); // ② (>= l) を、ちょうど (r-l) 個取り出すために (r-l+1) で分割 Split(BR, r - l + 1, out var B, out var C); // B が [l, r) // ③ B 全体に「代入」Lazyを載せる if (B != null) { B.lazy_flg = true; B.lazy_val = val; } // ④ 復元(順序厳守) node back = null; Marge(ref back, B, C); // back = (>= l) Marge(ref t, A, back); // t を元に戻す } // [l, r) を反転(1-index) private void RangeReverse(ref node t, int l, int r) { if (t == null || l >= r) return; // (=l) に分割 Split(t, l, out var A, out var BR); // (>=l) から [l,r) を切り出す(r-l+1 に注意) Split(BR, r - l + 1, out var B, out var C); // 真ん中に反転lazyを立てる if (B != null) B.rev = !B.rev; // 復元 node back = null; Marge(ref back, B, C); Marge(ref t, A, back); } // [l, r) の先頭を m にするよう左回転(std::rotate と同義) // 事前条件: l <= m <= r, 半開区間 private void Rotate(ref node t, int l, int m, int r) { if (t == null || l >= r || m == l || m == r) return; // 何もしないケースを早期終了 // reverse 3回 RangeReverse(ref t, l, r); RangeReverse(ref t, l, l + (r - m)); RangeReverse(ref t, l + (r - m), r); } //外部向け //indexにvalをぶっこむ 操作前のindex"以上"の要素は右にずれる 例:[1,2,3]にInsert(2,100) => [1,100,2,3] public void Insert(int index, long val) => Insert(ref root, index, new node(val, rand.Next())); public void Erase(int index) => Erase(ref root, index); //末尾に追加 public void PushBack(long val) => Insert(Count() + 1, val); public int Count() => root?.cnt ?? 0; public long this[int index] => Get(root, index); //[l,r)のモノイド積を取得 public long GetQueryVal(int l, int r) { return GetQueryVal(ref root, l, r); } //[l,r]に作用 public void RangeUpdate(int l, int r, long val) => RangeUpdate(ref root, l, r, val); //[l,r)を反転 public void RangeReverse(int l, int r) => RangeReverse(ref root, l, r); //[l,r)をn回左に順回シフト public void RangeRotateLeft(int l, int r, int n) { if (l >= r) return; int len = r - l; int k = ((n % len) + len) % len; // 0..len-1 に正規化 if (k == 0) return; int m = l + k; // 先頭が m になるように Rotate(ref root, l, m, r); } public void test() { for (int i = 1; i <= 10; ++i) PushBack(i); RangeRotateLeft(1, 6, 2); for (int i = 1; i <= Count(); ++i) Console.WriteLine(Get(root, i)); } public List dump() { var back = new List(); dump(root, back); return back; } private void dump(node t, List back) { if (t == null) return; t.Evaluate(); dump(t.left, back); back.Add(t.val); dump(t.right, back); } } public class Compress where T : struct, IComparable { //1indexだよ!!!! 例[1,5,8,9,5,5]=>[1,2,3,4,2,2] public Dictionary key2raw; public Dictionary raw2key; //やりたいこと 構築 生=>圧縮後 圧縮後=>生 public Compress(IEnumerable vector = null) { key2raw = new Dictionary(); raw2key = new Dictionary(); if (vector is { }) Build(vector); } public List Build(IEnumerable vector) { int cnt = 0; var back = new List(); foreach (var i in vector.OrderBy(i => i)) { if (!raw2key.ContainsKey(i)) { cnt++; raw2key.Add(i, cnt); key2raw.Add(cnt, i); } } foreach (var i in vector) back.Add(raw2key[i]); return back; } //インデクサは圧縮後=>生 public T this[int k] => key2raw[k]; public int Count => key2raw.Count; } /// /// 非負整数の集合を管理し、 /// 挿入・削除・最小/最大要素取得・k番目取得・XOR最小値取得・ /// 値の型は int(32ビット)に固定しています。 /// public class BinaryTrie32 { private const int B = 21; // int は32ビット private class Node { public int Count; // 部分木に含まれる要素数 public Node Left; // ビット0枝 public Node Right; // ビット1枝 public Node() { Count = 0; Left = null; Right = null; } } private Node root = null; // ———————————————— // 挿入/削除(点更新) // ———————————————— private Node Add(Node t, int val, int b) { if (t == null) t = new Node(); t.Count++; if (b < 0) return t; int bit = (val >> b) & 1; if (bit == 0) t.Left = Add(t.Left, val, b - 1); else t.Right = Add(t.Right, val, b - 1); return t; } private Node Sub(Node t, int val, int b) { if (t == null) return null; t.Count--; if (t.Count == 0) return null; if (b < 0) return t; int bit = (val >> b) & 1; if (bit == 0) t.Left = Sub(t.Left, val, b - 1); else t.Right = Sub(t.Right, val, b - 1); return t; } // ———————————————— // XOR最小値/最大値取得 // ———————————————— private int GetMin(Node t, int val, int b) { if (t == null) throw new InvalidOperationException("Trie is empty"); if (b < 0) return 0; int f = (val >> b) & 1; Node targetChild = (f == 0) ? t.Left : t.Right; if (targetChild == null) { f = 1 - f; targetChild = (f == 0) ? t.Left : t.Right; } int res = GetMin(targetChild, val, b - 1); return res | (f << b); } // ———————————————— // k番目小さい要素取得 // ———————————————— private int Get(Node t, int k, int b) { if (t == null || k < 1 || k > t.Count) throw new ArgumentOutOfRangeException(nameof(k)); int result = 0; while (b >= 0 && t != null) { int leftCount = t.Left != null ? t.Left.Count : 0; if (k <= leftCount) { t = t.Left; } else { result |= (1 << b); t = t.Right; k -= leftCount; } b--; } return result; } // ———————————————— // lower_bound/upper_bound の内部:要素 < val の個数を数える  // ———————————————— private int CountLower(Node t, int val, int b) { if (t == null || b < 0) return 0; int bit = (val >> b) & 1; int cnt = (bit == 1 && t.Left != null) ? t.Left.Count : 0; Node targetChild = (bit == 0) ? t.Left : t.Right; return cnt + CountLower(targetChild, val, b - 1); } // ———————————————— // public API // ———————————————— /// 集合の要素数を返す。 public int Size => root != null ? root.Count : 0; /// 空かどうかを返す。 public bool IsEmpty => root == null; /// x を集合に追加する。 public void Insert(int x) => root = Add(root, x, B - 1); /// x を集合から削除する(存在しない場合は何もしない)。 public void Erase(int x) => root = Sub(root, x, B - 1); /// x XOR v が最小となる v を返す。 public int MinXor(int x) => GetMin(root, x, B - 1); /// x XOR v が最大となる v を返す。 public int MaxXor(int x) => GetMin(root, ~x, B - 1); /// 集合内の最小要素を返す。 public int MinElement() => MinXor(0); /// 集合内の最大要素を返す。 public int MaxElement() => MaxXor(0); /// /// lower_bound(x): /// 集合内で値 x 以上の最小の要素の「番号」を取得します。 /// ここで「番号」とは小さい方から何番目か(1-indexed)を指します。 /// ⇒ 内部的には要素 < x の個数 + 1を返します。 /// つまり、集合の最大値より大きいvalを投げると、集合の要素数 + 1が返ってくる /// public int LowerBound(int val) => CountLower(root, val, B - 1) + 1; /// /// upper_bound(x): /// 集合内で値 x より大きい最小の要素の「番号」を取得します。 /// ここで「番号」とは小さい方から何番目か(1-indexed)を指します。 /// ⇒ 内部的には要素 ≤ x の個数 + 1を返します(val+1 を lower_bound しているため)。 /// つまり、集合の最大値以上のvalを投げると、集合の要素数 + 1が返ってくる /// public int UpperBound(int val) => CountLower(root, val + 1, B - 1) + 1; /// k 番目(1-indexed)に小さい要素を返す。 public int this[int k] => Get(root, k, B - 1); /// 要素 val の集合内での個数を返す。 public int Count(int val) { Node t = root; for (int i = B - 1; i >= 0 && t != null; i--) { int bit = (val >> i) & 1; t = (bit == 0) ? t.Left : t.Right; } return t != null ? t.Count : 0; } } public static class Extensions { public static Dictionary safe_addtion_for_dictionary_int(this Dictionary dic, T key) { if (dic.ContainsKey(key)) dic[key]++; else dic.Add(key, 1); return dic; } public static Dictionary safe_addtion_for_dictionary_long(this Dictionary dic, T key) { if (dic.ContainsKey(key)) dic[key]++; else dic.Add(key, 1); return dic; } public static Dictionary> safe_addtion_for_list_in_dictionary(this Dictionary> dic, T key, T2 value) { if (dic.ContainsKey(key)) dic[key].Add(value); else dic.Add(key, new List() { value }); return dic; } public static T list_pop_back(this List a) { var k = a[a.Count - 1]; a.RemoveAt(a.Count - 1); return k; } public static T chmin(ref this T a, T b) where T : struct, IComparable { if (a.CompareTo(b) > 0) return a = b; else return a; } public static T chmax(ref this T a, T b) where T : struct, IComparable { if (a.CompareTo(b) < 0) return a = b; else return a; } } internal class input { string[] soloinput; int t; public input() { soloinput = new string[0]; t = 0; } public string soloreed() { if (t < soloinput.Length) { return soloinput[t++]; } string input = Console.ReadLine(); while (input == "") { input = Console.ReadLine(); } soloinput = input.Split(" "); t = 0; return soloinput[t++]; } public int intreed() { return int.Parse(soloreed()); } public int[] arrayint(int N) { int[] A = new int[N]; for (int i = 0; i < N; i++) { A[i] = intreed(); } return A; } public long longreed() { return long.Parse(soloreed()); } public long[] arraylong(long N) { long[] A = new long[N]; for (long i = 0; i < N; i++) { A[i] = longreed(); } return A; } public decimal decimalreed() { return decimal.Parse(soloreed()); } public decimal[] arraydecimal(long N) { decimal[] A = new decimal[N]; for (decimal i = 0; i < N; i++) { A[(long)i] = decimalreed(); } return A; } } internal class mod { public long T { get; set; } public mod(long mod = 1000000007) { T = mod; } public long addition(long A, long B) { long C = A + B; return (long)C % T; } public long subtraction(long A, long B) { return ((A % T) - (B % T) + T) % T; } public long multiplication(long A, long B) { return ((A % T) * (B % T)) % T; } } internal class toolbox { string Y = "Yes"; string N = "No"; static input cin; private DateTime? startTime; public toolbox() { cin = new input(); } public long[] CumulativeSum(long[] A, bool mode = true) { if (mode == false) Array.Reverse(A); long[] back = new long[A.Length + 1]; back[0] = 0; for (int i = 1; i <= A.Length; i++) { back[i] = back[i - 1] + A[i - 1]; } if (mode == false) Array.Reverse(A); return back; } public long[] Eratosthenes(long A) { A++; var back = new List(); bool[] ch = new bool[A]; for (int i = 2; i < A; i++) ch[i] = true; for (long i = 2; i < Math.Sqrt(A); i++) { if (ch[i] == true) { back.Add(i); for (long t = 1; i * t < A; t++) { ch[i * t] = false; } } } for (long i = 0; i < A; i++) { if (ch[i] == true) back.Add(i); } return back.Distinct().ToArray(); } public void Swap(ref T a, ref T b) { var i = a; a = b; b = i; } public void LSwap(ref List A, int a, int b) { var i = A[a]; A[a] = A[b]; A[b] = i; } public long Gcd(long A, long B) { while (A != 0) { B %= A; Swap(ref A, ref B); } return B; } public long[] AllDivisors(long N) { var back = new List(); for (int i = 1; Math.Pow(i, 2) <= N; i++) { if (N % i == 0) { back.Add(i); back.Add(N / i); } } return back.Distinct().ToArray(); } public static IEnumerable ExhaustiveEnumeration(IEnumerable indata) { if (indata.Count() == 1) yield return new T[] { indata.First() }; foreach (var i in indata) { var used = new T[] { i }; var unused = indata.Except(used); foreach (var t in ExhaustiveEnumeration(unused)) yield return used.Concat(t).ToArray(); } //How to use //var allpattern = toolbox.ExhaustiveEnumeration(Enumerable.Range(1, N)); } public bool[,] bitallsearch(int N) { bool[,] back = new bool[(int)Math.Pow(2, N), N]; for (int i = 0; i < Math.Pow(2, N); i++) { for (int t = 0; t < N; t++) { var k = (i >> t) & 1; if (k == 1) { back[i, t] = true; } } } return back; } public static int BS(T[] A, T key) where T : IComparable { //このコード、定数倍が大変な事になってるので標準ライブラリを使いましょう(BinarySearch) int left = 0; int right = A.Length; int mid = 0; while (left < right) { mid = (left + right) / 2; if (A[mid].CompareTo(key) == 0) return mid; else if (A[mid].CompareTo(key) > 0) right = mid; else if (A[mid].CompareTo(key) < 0) left = mid + 1; } return -1; } public static int lower_bound(T[] a, T v) { return lower_bound(a, v, Comparer.Default); } public static int lower_bound(T[] A, T key, Comparer v) { int left = 0; int right = A.Length - 1; int mid = 0; var W = 0; while (left <= right) { mid = (left + right) / 2; W = v.Compare(A[mid], key); if (W == -1) left = mid + 1; else right = mid - 1; } return left; } public long[] prime_factorize(long N) { long T = N; var back = new List(); for (long i = 2; i * i <= T; i++) { if (T % i != 0) continue; while (T % i == 0) { back.Add(i); T /= i; } } if (T != 1) back.Add(T); return back.ToArray(); } public long[] One_dimensional_Coordinate_Compression(long[] A) { long[] back = new long[A.Length]; var T = A.Distinct().ToList(); T.Sort(); for (int i = 0; i < A.Length; i++) back[i] = T.BinarySearch(A[i]); return back; } public void setYN(string A = "Yes", string B = "No") { Y = A; N = B; } public void YN(bool ans) { if (ans) Console.WriteLine(Y); else Console.WriteLine(N); } public string[] x_dekakou(int H, int W) { var s = new string[H + 2]; for (int i = 0; i < W + 2; i++) { s[0] += "x"; s[H + 1] += "x"; } for (int i = 1; i < H + 1; i++) { //x場外 .白 #黒 s[i] = "x" + Console.ReadLine().Replace(" ", "") + "x"; } return s; } public List> x_dekakou_char(int H, int W) { var grid = new List>(H + 2); var border = new List(W + 2); for (int i = 0; i < W + 2; i++) border.Add('x'); grid.Add(new List(border)); for (int i = 0; i < H; i++) { var line = Console.ReadLine()?.Replace(" ", "") ?? string.Empty; var row = new List(W + 2); row.Add('x'); foreach (var c in line) row.Add(c); row.Add('x'); grid.Add(row); } grid.Add(new List(border)); return grid; } public List> x_dekakou_string(int H, int W) { var back = new List>(); for (int i = 0; i < H + 2; i++) back.Add(Enumerable.Repeat(-1, W + 2).ToList()); for (int i = 0; i < W + 2; i++) { back[0][i] = -1; back[H + 1][i] = -1; } for (int i = 1; i <= H; i++) { back[i][0] = -1; back[i][W + 1] = -1; for (int t = 1; t <= W; t++) back[i][t] = cin.intreed(); } return back; } /// /// 配列の指定位置以降を反転する /// /// 反転対象の配列 /// 反転開始位置(この位置以降が反転される) private void Reverse(T[] array, int begin) where T : IComparable { // 反転する要素が2個未満の場合は何もしない if (array.Length - begin < 2) return; // 両端から中央に向かって要素を交換 int left = begin; int right = array.Length - 1; while (left < right) { Swap(ref array[left], ref array[right]); left++; right--; } } /// /// 配列を辞書順で次の順列に変更する /// 全ての順列を列挙するには、事前に Array.Sort() でソートした配列を渡すこと /// /// 順列を生成する配列(事前ソート必須) /// 次の順列が存在する場合true、最大順列の場合false public bool NextPermutation(T[] array) where T : IComparable { // 辞書順で次に大きい順列を生成 // 1. 右端から降順でない位置を探す int pivotIndex = -1; for (int i = array.Length - 2; i >= 0; i--) { if (array[i].CompareTo(array[i + 1]) < 0) // 昇順ペア発見 { pivotIndex = i; break; } } // 最大順列に到達している場合 if (pivotIndex == -1) return false; // 2. pivotより大きい最右の要素と交換 for (int j = array.Length - 1; j > pivotIndex; j--) { if (array[pivotIndex].CompareTo(array[j]) < 0) { Swap(ref array[pivotIndex], ref array[j]); break; } } // 3. pivot以降を昇順に並べ直し Reverse(array, pivotIndex + 1); return true; // how to use // do{}while(NextPermutation) } /// /// 回文判定のコア処理(配列版) /// private bool IsPalindromeCore(T[] array, int left, int right) where T : IComparable { while (left < right) { if (array[left].CompareTo(array[right]) != 0) return false; left++; right--; } return true; } /// /// 回文判定のコア処理(文字列版) /// private bool IsPalindromeCore(string str, int left, int right) { while (left < right) { if (str[left] != str[right]) return false; left++; right--; } return true; } /// /// 配列全体が回文かどうかを判定 /// public bool IsPalindrome(T[] array) where T : IComparable { return IsPalindromeCore(array, 0, array.Length - 1); } /// /// 文字列全体が回文かどうかを判定 /// public bool IsPalindrome(string str) { return IsPalindromeCore(str, 0, str.Length - 1); } /// /// 指定範囲が回文かどうかを判定(配列版) /// public bool IsPalindrome(T[] array, int start, int end) where T : IComparable { return IsPalindromeCore(array, start, end); } /// /// 指定範囲が回文かどうかを判定(文字列版) /// public bool IsPalindrome(string str, int start, int end) { return IsPalindromeCore(str, start, end); } /// /// 指定長さの部分配列に回文が含まれるかを判定 /// public bool HasPalindrome(T[] array, int length) where T : IComparable { for (int i = 0; i <= array.Length - length; i++) { if (IsPalindromeCore(array, i, i + length - 1)) return true; } return false; } /// /// 指定長さの部分文字列に回文が含まれるかを判定 /// public bool HasPalindrome(string str, int length) { for (int i = 0; i <= str.Length - length; i++) { if (IsPalindromeCore(str, i, i + length - 1)) return true; } return false; } public long modpow(long x, long p, long mod = 1000000007) { long result = 1; x %= mod; while (p > 0) { if (p % 2 == 1) // pが奇数の場合 { result = (result * x) % mod; } x = (x * x) % mod; // xを二乗(これが繰り返し二乗) p /= 2; // pを半分にする } return result; } public void StartTimer() { startTime = DateTime.Now; } public void PrintElapsedTime(bool error_output = true) { //標準出力ではなくて標準エラー出力を使ってるのでatcoderのジャッジはこの出力を無視する つまり消さなくてok 便利だね if (startTime.HasValue) { var elapsed = DateTime.Now - startTime.Value; if (error_output) Console.Error.WriteLine($"Elapsed time: {elapsed.TotalMilliseconds} ms"); else Console.WriteLine($"Elapsed time: {elapsed.TotalMilliseconds} ms"); } else { Console.Error.WriteLine("Timer was not started."); } } } internal class Priority_Queue { toolbox toolbox = new toolbox(); public List<(long, long)> Queue { get; private set; } /// /// true==>大きいやつから出るよ false==>小さいやつからでるよ /// public bool revase { get; set; } public Priority_Queue(bool cnt = true) { Queue = new List<(long, long)>(); revase = cnt; } public void Enqueue(long a, long b) { if (revase == false) a *= -1; int i = Queue.Count, t; Queue.Add((a, b)); while (i != 0) { t = (i - 1) / 2; if (Queue[i].Item1 > Queue[t].Item1) { var k = Queue[i]; Queue[i] = Queue[t]; Queue[t] = k; i = t; } else { break; } } } public (long, long) Dequeue() { int a = Queue.Count - 1; var back = Queue[0]; Queue[0] = Queue[a]; Queue.RemoveAt(a); for (int i = 0, j; (j = 2 * i + 1) < a;) { if (j != a - 1 && Queue[j].Item1 < Queue[j + 1].Item1) j++; if (Queue[i].Item1 < Queue[j].Item1) { var k = Queue[i]; Queue[i] = Queue[j]; Queue[j] = k; i = j; } else { break; } } if (revase == false) back.Item1 *= -1; return back; } public (long, long) GetPeek() => (revase ? Queue[0].Item1 : Queue[0].Item1 * -1, Queue[0].Item2); } internal class Generic_Priority_Queue { toolbox toolbox = new toolbox(); public List<(long, T)> Queue { get; private set; } /// /// true==>大きいやつから出るよ false==>小さいやつからでるよ /// public bool revase { get; set; } public Generic_Priority_Queue(bool cnt = true) { Queue = new List<(long, T)>(); revase = cnt; } public void Enqueue(long a, T b) { if (revase == false) a *= -1; int i = Queue.Count, t; Queue.Add((a, b)); while (i != 0) { t = (i - 1) / 2; if (Queue[i].Item1 > Queue[t].Item1) { var k = Queue[i]; Queue[i] = Queue[t]; Queue[t] = k; i = t; } else { break; } } } public (long, T) Dequeue() { int a = Queue.Count - 1; var back = Queue[0]; Queue[0] = Queue[a]; Queue.RemoveAt(a); for (int i = 0, j; (j = 2 * i + 1) < a;) { if (j != a - 1 && Queue[j].Item1 < Queue[j + 1].Item1) j++; if (Queue[i].Item1 < Queue[j].Item1) { var k = Queue[i]; Queue[i] = Queue[j]; Queue[j] = k; i = j; } else { break; } } if (revase == false) back.Item1 *= -1; return back; } public (long, T) get_first() { if (Queue.Count == 0) return (default(long), default(T)); else return Queue[0]; } } }