Problem:
H: 魔法使いの塔

問題文

あなたが持っている魔導書には、 $N$ 個の魔法が載っています。

魔法には $1$ から $N$ までの番号がついていて、魔法 $i (1 \le i \le N)$ のコストははじめ整数 $A_i$ です。

あなたの目的は、魔導書に載っているすべての魔法を $1$ 回ずつ唱えることです。

魔法を唱えはじめる前に、あなたはクッキーを $K$ 枚食べることができます。クッキーを食べるのに時間はかかりません。

あなたはクッキーを $1$ 枚食べるたびに、コストが正の魔法を $1$ つ選び、そのコストを $1$ 下げることができます。

クッキーを食べたあと、あなたは魔法を唱え始めます。

あなたの MP ははじめ $M$ です。あなたは以下のどちらかを繰り返して、 $N$ 個の魔法を任意の順番で $1$ 回ずつ唱えます。

整数 $i (1 \le i \le N)$ を $1$ つ選び、魔法 $i$ を唱える。ただし、 現在の MP は魔法 $i$ のコスト以上でなければならない。

時間は経過しない。

MP を魔法 $i$ のコストだけ消費する。

休憩する。ただし、現在の MP を $m$ とすると、 $m < M$ でなければならない。

時間が $M - m$ 経過する。

MP を $1$ 回復する。

あなたが $N$ 個の魔法を任意の順番で $1$ 回ずつ唱えるためにかかる時間の最小値を求めてください。

制約

$1 \leq N \leq 10^5$

$1 \leq M \leq 10^6$

$0 \leq K \leq \sum_{i=1}^{N} A_i$

$1 \leq A_i \leq M$

入力はすべて整数である。

入力

入力は以下の形式で標準入力から与えられる。

$N$ $M$ $K$
$A_1$ $A_2$ $\ldots$ $A_N$

出力

$N$ 個の魔法を $1$ 回ずつ唱えるためにかかる時間の最小値を出力せよ。

入力例1

2 4 0
2 4

出力例1

3

どの魔法のコストも減らすことができないので、このまま魔法を唱えていくことにします。

まず、魔法 $1$ を唱えます。 MP を $2$ 消費するので、残りの MP は $4 - 2 = 2$ になります。

魔法 $2$ を唱えるには MP が $4$ 必要なので、このままでは魔法 $2$ を唱えることはできません。

休憩します。時間が $4 - 2 = 2$ 秒経過します。 MP を $1$ 回復するので、残りの MP は $2 + 1 = 3$ になります。

休憩します。時間が $4 - 3 = 1$ 秒経過します。 MP を $1$ 回復するので、残りの MP は $3 + 1 = 4$ になります。

魔法 $2$ を唱えます。 MP を $4$ 消費するので、残りの MP は $4 - 4 = 0$ になります。

以上より、時間を $2 + 1 = 3$ 秒かければ、魔法 $1,2$ を $1$ 回ずつ唱えることができます。
これより短い時間ですべての魔法を唱えることはできないので、求める答えは $3$ となります。

入力例2

3 9 6
2 3 9

出力例2

0

最終的な魔法のコストを $2, 2, 4$ とすると、休憩することなくすべての魔法を唱えることができます。

入力例3

3 16 2
6 9 9

出力例3

21

入力例4

2 1000000 0
1000000 1000000

出力例4

500000500000

答えは 32bit 整数で表せる範囲に収まらないことがあります。

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using static System.Math;
using Number = System.Int32;

namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri;
			var m = ri;
			var k = rl;
			var a = Enumerate(n, x => rl);


			var ans = a.Sum(x => x * (x + 1) / 2);
			var cnt = new long[m + 5];
			foreach (var x in a) cnt[x]++;
			//Σa_i - k - m 回は回復しないといけない
			//コストが大きいところでの回復をサボりたい
			// 1,2,3,...,x での回復を コスト x でまとめてサボれる
			long rem = m;
			Debug.WriteLine(ans);
			for (long i = m; i > 0 && k > 0; i--) {
				var u = Min(rem / i, cnt[i]);
				cnt[i] -= u; rem -= i * u; ans -= u * i * (i + 1) / 2;
				var mi = Min(k, cnt[i]);
				cnt[i] -= mi; cnt[i - 1] += mi; k -= mi; ans -= i * mi;
			}
			for (long i = m; i > 0; i--) while (cnt[i] > 0) {
					if (rem >= i) { rem -= i; cnt[i]--; ans -= i * (i + 1) / 2; }
					else { ans -= rem * (rem + 1) / 2; rem = 0; break; }

				}
			Console.WriteLine(ans);

		}

		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n];
			for (int i = 0; i < a.Length; ++i) a[i] = f(i);
			return a;
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = true });
		var solver = new Program.Solver();
		//* 
		var t = new System.Threading.Thread(solver.Solve, 50000000);
		//t.Start();
		//t.Join();
		//*/
		solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion