Problem:
Score : 600 points

Problem Statement

We have one slime.

You can set the health of this slime to any integer value of your choice.

A slime reproduces every second by spawning another slime that has strictly less health. You can freely choose the health of each new slime. The first reproduction of our slime will happen in one second.

Determine if it is possible to set the healths of our first slime and the subsequent slimes spawn so that the multiset of the healths of the 2^N slimes that will exist in N seconds equals a multiset S.

Here S is a multiset containing 2^N (possibly duplicated) integers: S_1,~S_2,~...,~S_{2^N}.

Constraints

All values in input are integers.

1 \leq N \leq 18

1 \leq S_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
S_1 S_2 ... S_{2^N}

Output

If it is possible to set the healths of the first slime and the subsequent slimes spawn so that the multiset of the healths of the 2^N slimes that will exist in N seconds equals S, print Yes; otherwise, print No.

Sample Input 1

2
4 2 3 1

Sample Output 1

Yes

We will show one way to make the multiset of the healths of the slimes that will exist in 2 seconds equal to S.

First, set the health of the first slime to 4.

By letting the first slime spawn a slime whose health is 3, the healths of the slimes that exist in 1 second can be 4,~3.

Then, by letting the first slime spawn a slime whose health is 2, and letting the second slime spawn a slime whose health is 1, the healths of the slimes that exist in 2 seconds can be 4,~3,~2,~1, which is equal to S as multisets.

Sample Input 2

2
1 2 3 1

Sample Output 2

Yes

S may contain multiple instances of the same integer.

Sample Input 3

1
1 1

Sample Output 3

No

Sample Input 4

5
4 3 5 3 1 2 7 8 7 4 6 3 7 2 3 6 2 7 3 2 6 7 3 4 6 7 3 4 2 5 2 3

Sample Output 4

No

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace FertiLib.Contest.F
{
	static class Program
	{
		public static void Solve(Scanner cin)
		{
			int n = cin.ReadInt();
			var s = cin.ReadIntArray(1 << n);
			var ms = new Set<int>();
			ms.IsMultiSet = true;

			foreach (var e in s)
			{
				ms.Add(e);
			}

			var now = new List<int>();

			int ad = ms.Max();
			now.Add(ad);
			ms.Remove(ad);

			var prev = new List<int>(now);
			bool ok = true;

			for (int i = 0; i < n; i++)
			{
				foreach (var e in prev)
				{
					int x = ms.LowerBound(e);

					if (x <= 0) ok = false;
					else
					{
						now.Add(ms[x - 1]);
						ms.Remove(ms[x - 1]);
					}
				}

				prev = new List<int>(now);
			}

			YesNo(ok);
		}

		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);
			var cin = new Scanner();
			Solve(cin);
			Console.Out.Flush();
		}

		public static void YESNO(bool condition) => Console.WriteLine(condition ? "YES" : "NO");
		public static void YesNo(bool condition) => Console.WriteLine(condition ? "Yes" : "No");
		public static void yesno(bool condition) => Console.WriteLine(condition ? "yes" : "no");

		public static bool Chmax<T>(ref T a, T b) where T : IComparable<T>
		{
			if (a.CompareTo(b) >= 0) return false;
			a = b;
			return true;
		}
		public static bool Chmin<T>(ref T a, T b) where T : IComparable<T>
		{
			if (a.CompareTo(b) <= 0) return false;
			a = b;
			return true;
		}
	}

	public class Set<T> : IEnumerable<T> where T : IComparable<T>
	{
		Node root;
		readonly IComparer<T> comparer;
		readonly Node nil;
		public bool IsMultiSet { get; set; }

		public Set() : this(Comparer<T>.Default) { }
		public Set(IComparer<T> comparer)
		{
			nil = new Node(default);
			root = nil;
			this.comparer = comparer;
		}
		public Set(Comparison<T> comparison) : this(Comparer<T>.Create(comparison)) { }

		public T this[int index]
		{
			get
			{
				if (index < 0 || root.Count < index) throw new ArgumentOutOfRangeException();
				return Find(root, index);
			}
		}

		public bool Add(T x) => Insert(ref root, x);
		public bool Remove(T x) => Erase(ref root, x);
		public void RemoveAt(int index)
		{
			if (index < 0 || Count < index) throw new ArgumentOutOfRangeException();
			EraseAt(ref root, index);
		}
		public bool Contains(T x) => EqualRange(x) > 0;
		public int LowerBound(T x) => BinarySearch(root, x, false);
		public int UpperBound(T x) => BinarySearch(root, x, true);
		public int EqualRange(T x) => UpperBound(x) - LowerBound(x);

		public void Clear() => root = nil;

		public T Min() => root.Min.Value;
		public T Max() => root.Max.Value;

		public T[] Items
		{
			get
			{
				var a = new T[root.Count];
				var k = 0;
				Walk(root, a, ref k);
				return a;
			}
		}
		public int Count => root.Count;
		public int Height => root.Height;

		public IEnumerator<T> GetEnumerator() { return Items.AsEnumerable().GetEnumerator(); }
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();

		bool Insert(ref Node p, T x)
		{
			if (p.Count == 0)
			{
				p = new Node(x);
				p.Left = p.Right = nil;
				p.Update();
				return true;
			}
			bool ret;
			var t = comparer.Compare(p.Value, x);
			if (t > 0)
			{
				ret = Insert(ref p.Left, x);
			}
			else if (t < 0)
			{
				ret = Insert(ref p.Right, x);
			}
			else
			{
				if (IsMultiSet == true) ret = Insert(ref p.Left, x);
				else return false;
			}
			Balance(ref p);
			return ret;
		}

		bool Erase(ref Node p, T x)
		{
			if (p.Count == 0) return false;
			var t = comparer.Compare(p.Value, x);
			bool ret;
			if (t < 0) ret = Erase(ref p.Right, x);
			else if (t > 0) ret = Erase(ref p.Left, x);
			else
			{
				ret = true;
				if (p.Right.Count == 0) { p = p.Left; return true; }
				if (p.Left.Count == 0) { p = p.Right; return true; }

				p.Value = p.Left.Max.Value;
				Erase(ref p.Left, p.Left.Max.Value);
			}
			Balance(ref p);

			return ret;
		}

		void EraseAt(ref Node p, int index)
		{
			var count = p.Left.Count;
			if (index < count) EraseAt(ref p.Left, index);
			else if (index > count) EraseAt(ref p.Right, index - count - 1);
			else
			{
				if (p.Left.Count == 0) { p = p.Right; return; }
				if (p.Right.Count == 0) { p = p.Left; return; }

				p.Value = p.Left.Max.Value;
				EraseAt(ref p.Left, index - 1);
			}

			Balance(ref p);
		}

		void Walk(Node t, T[] a, ref int k)
		{
			if (t.Count == 0) return;
			Walk(t.Left, a, ref k);
			a[k++] = t.Value;
			Walk(t.Right, a, ref k);
		}

		void Balance(ref Node p)
		{
			var balance = p.Left.Height - p.Right.Height;
			if (balance < -1)
			{
				if (p.Right.Left.Height - p.Right.Right.Height > 0) RotateR(ref p.Right);
				RotateL(ref p);
			}
			else if (balance > 1)
			{
				if (p.Left.Left.Height - p.Left.Right.Height < 0) RotateL(ref p.Left);
				RotateR(ref p);
			}
			else p.Update();
		}

		T Find(Node p, int index)
		{
			if (index < p.Left.Count) return Find(p.Left, index);
			if (index > p.Left.Count) return Find(p.Right, index - p.Left.Count - 1);
			return p.Value;
		}

		void RotateL(ref Node p)
		{
			var r = p.Right;
			p.Right = r.Left;
			r.Left = p;
			p.Update();
			r.Update();
			p = r;
		}

		void RotateR(ref Node p)
		{
			var l = p.Left;
			p.Left = l.Right;
			l.Right = p;
			p.Update();
			l.Update();
			p = l;
		}

		int BinarySearch(Node p, T x, bool isUpperBound)
		{
			if (p.Count == 0) throw new NullReferenceException();

			var node = p;

			var ret = 0;

			while (p.Count != 0)
			{
				var cmp = p.Value.CompareTo(x);
				if (cmp > 0 || (!isUpperBound && cmp == 0))
				{
					p = p.Left;
				}
				else
				{
					ret += p.Left.Count + 1;
					p = p.Right;
				}
			}

			return ret;
		}

		public override string ToString()
		{
			return string.Join(", ", Items);
		}

		class Node
		{
			public Node Left, Right;
			public T Value { get; set; }

			public int Count { get; private set; }
			public int Height { get; private set; }

			public Node Min
			{
				get
				{
					if (Left.Count == 0) return this;
					else return Left.Min;
				}
			}

			public Node Max
			{
				get
				{
					if (Right.Count == 0) return this;
					else return Right.Max;
				}
			}

			public Node(T value) => Value = value;

			public void Update()
			{
				Count = Left.Count + Right.Count + 1;
				Height = Math.Max(Left.Height, Right.Height) + 1;
			}

			public override string ToString() => $"Count = {Count}, Value = {Value}";
		}
	}

	static class Util
	{
		public static string Join<T>(this IEnumerable<T> x, string separator = "") => string.Join(separator, x);
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] separator = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string Read() => ReadString();

		public string ReadString()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(separator, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return ReadString();
			i = 0;
			return s[i++];
		}

		public string[] ReadStringArray(int N)
		{
			string[] Array = new string[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadString();
			}
			return Array;
		}

		public int ReadInt()
		{
			return int.Parse(ReadString());
		}

		public int[] ReadIntArray(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadInt() + add;
			}
			return Array;
		}

		public long ReadLong()
		{
			return long.Parse(ReadString());
		}

		public long[] ReadLongArray(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadLong() + add;
			}
			return Array;
		}

		public double ReadDouble()
		{
			return double.Parse(ReadString());
		}

		public double[] ReadDoubleArray(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadDouble() + add;
			}
			return Array;
		}

		public T1 ReadValue<T1>() => (T1)Convert.ChangeType(ReadString(), typeof(T1));

		public (T1, T2) ReadValue<T1, T2>()
		{
			var inputs = ReadStringArray(2);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			return (v1, v2);
		}

		public (T1, T2, T3) ReadValue<T1, T2, T3>()
		{
			var inputs = ReadStringArray(3);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			return (v1, v2, v3);
		}

		public (T1, T2, T3, T4) ReadValue<T1, T2, T3, T4>()
		{
			var inputs = ReadStringArray(4);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			return (v1, v2, v3, v4);
		}

		public (T1, T2, T3, T4, T5) ReadValue<T1, T2, T3, T4, T5>()
		{
			var inputs = ReadStringArray(5);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			return (v1, v2, v3, v4, v5);
		}

		public (T1, T2, T3, T4, T5, T6) ReadValue<T1, T2, T3, T4, T5, T6>()
		{
			var inputs = ReadStringArray(6);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
			return (v1, v2, v3, v4, v5, v6);
		}

		public (T1, T2, T3, T4, T5, T6, T7) ReadValue<T1, T2, T3, T4, T5, T6, T7>()
		{
			var inputs = ReadStringArray(7);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
			var v7 = (T7)Convert.ChangeType(inputs[6], typeof(T7));
			return (v1, v2, v3, v4, v5, v6, v7);
		}

		public T1[] ReadValueArray<T1>(int N)
		{
			var v1 = new T1[N];
			for (int i = 0; i < N; i++)
			{
				v1[i] = ReadValue<T1>();
			}
			return v1;
		}

		public (T1[], T2[]) ReadValueArray<T1, T2>(int N)
		{
			var (v1, v2) = (new T1[N], new T2[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2) = ReadValue<T1, T2>();
				v1[i] = t1;
				v2[i] = t2;
			}
			return (v1, v2);
		}

		public (T1[], T2[], T3[]) ReadValueArray<T1, T2, T3>(int N)
		{
			var (v1, v2, v3) = (new T1[N], new T2[N], new T3[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3) = ReadValue<T1, T2, T3>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
			}
			return (v1, v2, v3);
		}

		public (T1[], T2[], T3[], T4[]) ReadValueArray<T1, T2, T3, T4>(int N)
		{
			var (v1, v2, v3, v4) = (new T1[N], new T2[N], new T3[N], new T4[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4) = ReadValue<T1, T2, T3, T4>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
			}
			return (v1, v2, v3, v4);
		}

		public (T1[], T2[], T3[], T4[], T5[]) ReadValueArray<T1, T2, T3, T4, T5>(int N)
		{
			var (v1, v2, v3, v4, v5) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5) = ReadValue<T1, T2, T3, T4, T5>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
			}
			return (v1, v2, v3, v4, v5);
		}

		public (T1[], T2[], T3[], T4[], T5[], T6[]) ReadValueArray<T1, T2, T3, T4, T5, T6>(int N)
		{
			var (v1, v2, v3, v4, v5, v6) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N], new T6[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5, t6) = ReadValue<T1, T2, T3, T4, T5, T6>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
				v6[i] = t6;
			}
			return (v1, v2, v3, v4, v5, v6);
		}

		public (T1[], T2[], T3[], T4[], T5[], T6[], T7[]) ReadValueArray<T1, T2, T3, T4, T5, T6, T7>(int N)
		{
			var (v1, v2, v3, v4, v5, v6, v7) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N], new T6[N], new T7[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5, t6, t7) = ReadValue<T1, T2, T3, T4, T5, T6, T7>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
				v6[i] = t6;
				v7[i] = t7;
			}
			return (v1, v2, v3, v4, v5, v6, v7);
		}
	}
}