結果
| 問題 |
No.2665 Minimize Inversions of Deque
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-03-08 21:47:56 |
| 言語 | C# (.NET 8.0.404) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 8,960 bytes |
| コンパイル時間 | 8,116 ms |
| コンパイル使用メモリ | 166,760 KB |
| 実行使用メモリ | 242,704 KB |
| 最終ジャッジ日時 | 2024-09-29 19:28:50 |
| 合計ジャッジ時間 | 20,110 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 1 WA * 39 |
コンパイルメッセージ
復元対象のプロジェクトを決定しています... /home/judge/data/code/main.csproj を復元しました (93 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 enable
using System.Numerics;
static class Extensions
{
public static T[] Repeat<T>(this int time, Func<T> F) => Enumerable.Range(0, time).Select(_ => F()).ToArray();
}
abstract class SelfBalancingTreeBase<T>
{
protected class Node
{
public required T Data { get; set; }
public Node? L { get; set; }
public Node? R { get; set; }
public int Height { get; set; } = 1;
public int Size { get; set; } = 1;
public Node? this[bool right]
{
get => right ? R : L;
set { if (right) R = value; else L = value; }
}
}
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? Root { get; set; }
protected static int Size(Node? node) => node?.Size ?? 0;
protected static int Height(Node? node) => node?.Height ?? 0;
protected static int HeightDiff(Node node) => Height(node.R) - Height(node.L);
protected static void Update(Node node)
{
node.Height = Math.Max(Height(node.L), Height(node.R)) + 1;
node.Size = Size(node.L) + Size(node.R) + 1;
}
protected static Node? DeleteMin(Node node, Node swap)
{
if (node.L == null) { swap.Data = node.Data; return node.R; }
node.L = DeleteMin(node.L, swap);
return Balance(node);
}
protected static Node Balance(Node node)
{
var diff = HeightDiff(node);
if (diff < -1 || 1 < diff)
{
var right = diff > 0;
var next = node[right]!;
if (HeightDiff(next) * diff < 0) node[right] = Rotate(next, right);
return Rotate(node, !right);
}
Update(node);
return node;
}
protected static Node Rotate(Node node, bool right)
{
var n0 = node[!right]!;
node[!right] = n0[right];
Update(node);
n0[right] = node;
Update(n0);
return n0;
}
public bool DeleteAt(int index) => Size(Root) != Size(Root = DeleteAt(Root, index));
static Node? DeleteAt(Node? node, int index)
{
if (node == null) return null;
var ls = Size(node.L);
if (index == ls)
{
if (node.R == null) return node.L;
node.R = DeleteMin(node.R, node);
}
else
{
var right = index > ls;
node[right] = DeleteAt(node[right], right ? index - 1 - ls : index);
}
return Balance(node);
}
protected IEnumerator<T> GetEnumerator()
{
var stack = new Stack<Node>();
var lastR = Root;
while (lastR != null || stack.Count > 0)
{
while (lastR != null)
{
stack.Push(lastR);
lastR = lastR.L;
}
var last = stack.Pop();
yield return last.Data;
lastR = last.R;
}
}
public int Count { get => Size(Root); }
}
abstract class SelfBalancingTree<TKey, TValue> : SelfBalancingTreeBase<KeyValuePair<TKey, TValue>> where TKey : IComparable<TKey>
{
public int MaxIndex(TKey key, bool include) => Bound(Root, key, true, include).Item1;
public int MinIndex(TKey key, bool include) => Bound(Root, key, false, include).Item1;
protected static (int, Node?) Bound(Node? node, TKey key, bool max, bool include)
{
var index = max ? -1 : 0;
Node? res = null;
while (node != null)
{
var comp = key.CompareTo(node.Data.Key);
var left = comp < 0 || comp == 0 && (max ^ include);
if (!left) index += Size(node.L) + 1;
if (max ^ left) res = node;
node = left ? node.L : node.R;
}
return (index, res);
}
public int CountKey(TKey key) => MaxIndex(key, true) - MaxIndex(key, false);
public ValueTuple<TKey>? MaxKey(TKey key, bool include) => ToOptionalKey(Bound(Root, key, true, include).Item2);
public ValueTuple<TKey>? MinKey(TKey key, bool include) => ToOptionalKey(Bound(Root, key, false, include).Item2);
static ValueTuple<TKey>? ToOptionalKey(Node? node) => node == null ? null : new(node.Data.Key);
protected static Node? Find(Node? node, TKey key)
{
var res = Bound(node, key, false, true).Item2;
return res != null && key.CompareTo(res.Data.Key) == 0 ? res : null;
}
protected static KeyValuePair<TKey, TValue> CreateData(TKey key, TValue value) => new(key, value);
protected void Insert(KeyValuePair<TKey, TValue> data) => Root = Insert(Root, data);
static Node Insert(Node? node, KeyValuePair<TKey, TValue> data)
{
if (node == null) return new Node{ Data = data };
var right = data.Key.CompareTo(node.Data.Key) >= 0;
node[right] = Insert(node[right], data);
return Balance(node);
}
public bool Delete(TKey key) => Size(Root) != Size(Root = Delete(Root, key));
static Node? Delete(Node? node, TKey key)
{
if (node == null) return null;
var comp = key.CompareTo(node.Data.Key);
if (comp == 0)
{
if (node.R == null) return node.L;
node.R = DeleteMin(node.R, node);
}
else
{
var right = comp > 0;
node[right] = Delete(node[right], key);
}
return Balance(node);
}
}
class FlexibleArray<T> : SelfBalancingTreeBase<T>
{
public T this[int index]
{
get => At(Root, index).Data;
set => At(Root, index).Data = value;
}
public new IEnumerator<T> GetEnumerator() => base.GetEnumerator();
public void Insert(T data, int index) => Root = Insert(Root, data, index);
static Node Insert(Node? node, T data, int index)
{
if (node == null) return new Node{ Data = data };
var ls = Size(node.L);
var right = index > ls;
node[right] = Insert(node[right], data, right ? index - 1 - ls : index);
return Balance(node);
}
}
class OrderedMultiSet<T> : SelfBalancingTree<T, ValueTuple> where T : IComparable<T>
{
public bool Contains(T key) => Find(Root, key) != null;
public T At(int index) => At(Root, index).Data.Key;
public void Insert(T key) => Insert(CreateData(key, ValueTuple.Create()));
public new IEnumerator<T> GetEnumerator()
{
using var e = base.GetEnumerator();
while (e.MoveNext()) yield return e.Current.Key;
}
}
class AtCoder
{
object? Solve()
{
var t = Int();
for (var i = 0; i < t; i++)
{
var (x, a) = Solve2();
Out(x);
Out(a, " ");
}
return null;
}
(long, int[]) Solve2()
{
var n = Int();
var pz = n.Repeat(Int);
var s = new OrderedMultiSet<int>();
var q = new FlexibleArray<int>();
s.Insert(pz[0]);
q.Insert(pz[0], 0);
var x = 0L;
for (var i = 1; i < n; i++)
{
var p = pz[i];
var c = s.MinIndex(p, false);
x += Math.Min(c, i - c);
if (c == i - c)
{
var h = q[0];
if (p < h) q.Insert(p, 0);
else q.Insert(p, i);
continue;
}
if (c > i - c) q.Insert(p, i);
else q.Insert(p, 0);
}
var res = new List<int>();
foreach (var v in q) res.Add(v);
return (x, res.ToArray());
}
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 IDE0051
string 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
}