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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using E = System.Linq.Enumerable;
using System.Numerics;
using System.Collections;

partial class Solver
{
    public void Run()
    {
        var N = ni();
        var S = ni(1 << N);
        Array.Sort(S);
        Array.Reverse(S);

        bool ans = true;

        var set = new MultiSet<int>();

        foreach (var s in S)
        {
            set.Add(s);
        }

        var current = new List<int>();
        current.Add(S[0]);
        set.Remove(S[0]);

        while (current.Count < S.Length)
        {
            var added = new List<int>();

            foreach (var x in current)
            {
                var index = set.IndexOfLowerBound(x);
                index--;
                if (index < 0 || index >= set.Count)
                {
                    ans = false;
                    break;
                }
                int y = set.At(index);
                added.Add(y);
                set.Remove(y);
            }
            if (!ans) break;
            current.AddRange(added);
        }

        cout.WriteLine(ans ? "Yes" : "No");
    }

}

public partial class MultiSet<T> : IEnumerable<T>
{
    private readonly Set<Tuple<T, int>> set;
    private int _nonce = 0;
    public MultiSet() : this(Comparer<T>.Default)
    {
    }

    public MultiSet(IComparer<T> comparer)
    {
        set = new Set<Tuple<T, int>>(new TupleComparer(comparer));
    }

    class TupleComparer : IComparer<Tuple<T, int>>
    {
        private readonly IComparer<T> _comparer;
        public TupleComparer(IComparer<T> comparer)
        {
            _comparer = comparer;
        }

        public int Compare(Tuple<T, int> x, Tuple<T, int> y)
        {
            var cmp = _comparer.Compare(x.Item1, y.Item1);
            if (cmp != 0) return cmp;
            return x.Item2.CompareTo(y.Item2);
        }
    }

    public int Count { get { return set.Count; } }

    public int CountOf(T value)
    {
        return IndexOfUpperBound(value) - IndexOfLowerBound(value);
    }

    public void Add(T value)
    {
        set.Add(Tuple.Create(value, _nonce++));
    }

    public T At(int index)
    {
        return set.At(index).Item1;
    }

    public void Remove(T value)
    {
        var index = IndexOfLowerBound(value);
        if (index < set.Count)
        {
            var v = set.At(index);
            if (v.Item1.Equals(value))
            {
                set.Remove(v);
            }
        }
    }

    public int IndexOfLowerBound(T value)
    {
        return set.IndexOfLowerBound(Tuple.Create(value, int.MinValue));
    }

    public int IndexOfUpperBound(T value)
    {
        return set.IndexOfUpperBound(Tuple.Create(value, int.MaxValue));
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach (var v in set)
        {
            yield return v.Item1;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public partial class Set<T>
{
    private Node root = null;
    private readonly IComparer<T> _comparer;

    public Set() : this(Comparer<T>.Default)
    {
    }

    public Set(IComparer<T> comparer)
    {
        _comparer = comparer;
    }

    virtual protected bool AllowMultiple { get { return true; } }

    public int Count { get { return root == null ? 0 : root.Count; } }

    public bool Contains(T value)
    {
        var node = root;
        while (node != null)
        {
            int cmp = _comparer.Compare(value, node.Value);
            if (cmp == 0)
            {
                return true;
            }
            node = (cmp < 0) ? node.Left : node.Right;
        }
        return false;
    }

    public int IndexOfLowerBound(T value)
    {
        var node = root;
        int index = 0;
        while (node != null)
        {
            int leftCount = node.Left == null ? 0 : node.Left.Count;
            int cmp = _comparer.Compare(value, node.Value);
            if (cmp <= 0)
            {
                node = node.Left;
            }
            else
            {
                index += leftCount + 1;
                node = node.Right;
            }
        }
        return index;
    }

    public int IndexOfUpperBound(T value)
    {
        var node = root;
        int index = 0;
        while (node != null)
        {
            int leftCount = node.Left == null ? 0 : node.Left.Count;
            int cmp = _comparer.Compare(value, node.Value);
            if (cmp < 0)
            {
                node = node.Left;
            }
            else
            {
                index += leftCount + 1;
                node = node.Right;
            }
        }
        return index;
    }

    public T At(int index)
    {
        var node = root;
        while (node != null)
        {
            int leftCount = node.Left == null ? 0 : node.Left.Count;
            if (index == leftCount) return node.Value;
            if (index < leftCount)
            {
                node = node.Left;
            }
            else
            {
                node = node.Right;
                index -= leftCount + 1;
            }
        }
        throw new ArgumentOutOfRangeException("index");
    }

    public void Add(T value)
    {
        root = Add(root, value);
        root.Color = Node.BLACK;
    }

    private Node Add(Node h, T value)
    {
        if (h == null)
        {
            return new Node(value);
        }

        if (IsRed(h.Left) && IsRed(h.Right))
        {
            ColorFlip(h);
        }

        int cmp = _comparer.Compare(value, h.Value);
        if (cmp == 0)
        {
            // do nothing
        }
        else if (cmp < 0)
        {
            h.Left = Add(h.Left, value);
            h.FixCount();
        }
        else
        {
            h.Right = Add(h.Right, value);
            h.FixCount();
        }

        if (IsRed(h.Right) && !IsRed(h.Left))
        {
            h = RotateLeft(h);
        }

        if (IsRed(h.Left) && IsRed(h.Left.Left))
        {
            h = RotateRight(h);
        }

        return h;
    }

    public void RemoveMin()
    {
        root = RemoveMin(root);
        if (root != null)
        {
            root.Color = Node.BLACK;
        }
    }

    private Node RemoveMin(Node h)
    {
        if (h.Left == null)
        {
            return null;
        }

        if (!IsRed(h.Left) && !IsRed(h.Left.Left))
        {
            h = MoveRedLeft(h);
        }

        h.Left = RemoveMin(h.Left);
        h.FixCount();
        return FixUp(h);
    }

    public void Remove(T value)
    {
        root = Remove(root, value);
        if (root != null)
        {
            root.Color = Node.BLACK;
        }
    }

    private Node Remove(Node h, T value)
    {
        if (_comparer.Compare(value, h.Value) < 0)
        {
            if (h.Left == null)
            {
                throw new KeyNotFoundException("value");
            }

            if (!IsRed(h.Left) && !IsRed(h.Left.Left))
            {
                h = MoveRedLeft(h);
            }
            h.Left = Remove(h.Left, value);
            h.FixCount();
        }
        else
        {
            if (IsRed(h.Left))
            {
                h = RotateRight(h);
            }

            if (h.Right == null)
            {
                if (_comparer.Compare(value, h.Value) == 0)
                {
                    return null;
                }

                throw new KeyNotFoundException("value");
            }

            if (!IsRed(h.Right) && !IsRed(h.Right.Left))
            {
                h = MoveRedRight(h);
            }

            if (_comparer.Compare(value, h.Value) == 0)
            {
                h.Value = Min(h.Right).Value;
                h.Right = RemoveMin(h.Right);
                h.FixCount();
            }
            else
            {
                h.Right = Remove(h.Right, value);
                h.FixCount();
            }
        }

        return FixUp(h);
    }

    private static Node MoveRedLeft(Node h)
    {
        ColorFlip(h);

        if (IsRed(h.Right.Left))
        {
            h.Right = RotateRight(h.Right);
            h.FixCount();
            h = RotateLeft(h);
            ColorFlip(h);
        }

        return h;
    }

    private static Node MoveRedRight(Node h)
    {
        ColorFlip(h);

        if (IsRed(h.Left.Left))
        {
            h = RotateRight(h);
            ColorFlip(h);
        }

        return h;
    }

    static private Node RotateLeft(Node h)
    {
        Node x = h.Right;
        h.Right = x.Left;
        x.Left = h;

        x.Color = h.Color;
        h.Color = Node.RED;
        h.FixCount();
        x.FixCount();
        return x;
    }

    private static Node RotateRight(Node h)
    {
        Node x = h.Left;
        h.Left = x.Right;
        x.Right = h;

        x.Color = h.Color;
        h.Color = Node.RED;
        h.FixCount();
        x.FixCount();
        return x;
    }

    private static bool IsRed(Node h)
    {
        return h != null && h.Color == Node.RED;
    }

    static private void ColorFlip(Node h)
    {
        h.Color = !h.Color;
        h.Left.Color = !h.Left.Color;
        h.Right.Color = !h.Right.Color;
    }

    static private Node Min(Node h)
    {
        while (h.Left != null)
        {
            h = h.Left;
        }
        return h;
    }

    static private Node FixUp(Node h)
    {
        if (IsRed(h.Right))
        {
            h = RotateLeft(h);
        }

        if (h.Left != null && IsRed(h.Left) && IsRed(h.Left.Left))
        {
            h = RotateRight(h);
        }

        if (IsRed(h.Left) && IsRed(h.Right))
        {
            ColorFlip(h);
        }
        h.FixCount();
        return h;
    }

    private class Node
    {
        public const bool RED = true;
        public const bool BLACK = false;
        public T Value;
        public bool Color = RED;
        public Node Left = null;
        public Node Right = null;
        public int Count = 1;
        public Node(T value)
        {
            this.Value = value;
        }

        public void FixCount()
        {
            this.Count = 1;
            if (Left != null) Count += Left.Count;
            if (Right != null) Count += Right.Count;
        }
    }
}

public partial class Set<T> : IEnumerable<T>
{
    public IEnumerator<T> GetEnumerator()
    {
        var node = root;
        var stack = new Stack<Node>();
        while (node != null || stack.Count > 0)
        {
            while (node != null)
            {
                stack.Push(node);
                node = node.Left;
            }
            node = stack.Pop();
            yield return node.Value;
            node = node.Right;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

// PREWRITEN CODE BEGINS FROM HERE
partial class Solver : Scanner
{
    public static void Main(string[] args)
    {
#if LOCAL
        new Solver(Console.In, Console.Out).Run();
#else
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver(Console.In, Console.Out).Run();
        Console.Out.Flush();
#endif
    }

#pragma warning disable IDE0052
    private readonly TextReader cin;
    private readonly TextWriter cout;
#pragma warning restore IDE0052

    public Solver(TextReader reader, TextWriter writer)
        : base(reader)
    {
        this.cin = reader;
        this.cout = writer;
    }
    public Solver(string input, TextWriter writer)
        : this(new StringReader(input), writer)
    {
    }

#pragma warning disable IDE1006
#pragma warning disable IDE0051
    private int ni() { return NextInt(); }
    private int[] ni(int n) { return NextIntArray(n); }
    private long nl() { return NextLong(); }
    private long[] nl(int n) { return NextLongArray(n); }
    private double nd() { return NextDouble(); }
    private double[] nd(int n) { return NextDoubleArray(n); }
    private string ns() { return Next(); }
    private string[] ns(int n) { return NextArray(n); }
#pragma warning restore IDE1006
#pragma warning restore IDE0051
}

public static class LinqPadExtension
{
    static public T Dump<T>(this T obj)
    {
#if LOCAL
        return LINQPad.Extensions.Dump(obj);
#else
        return obj;
#endif
    }
}
public class Scanner
{
    private readonly TextReader Reader;
    private readonly Queue<string> TokenQueue = new Queue<string>();
    private readonly CultureInfo ci = CultureInfo.InvariantCulture;

    public Scanner()
        : this(Console.In)
    {
    }

    public Scanner(TextReader reader)
    {
        this.Reader = reader;
    }

    public int NextInt() { return int.Parse(Next(), ci); }
    public long NextLong() { return long.Parse(Next(), ci); }
    public double NextDouble() { return double.Parse(Next(), ci); }
    public string[] NextArray(int size)
    {
        var array = new string[size];
        for (int i = 0; i < size; i++) array[i] = Next();
        return array;
    }
    public int[] NextIntArray(int size)
    {
        var array = new int[size];
        for (int i = 0; i < size; i++) array[i] = NextInt();
        return array;
    }

    public long[] NextLongArray(int size)
    {
        var array = new long[size];
        for (int i = 0; i < size; i++) array[i] = NextLong();
        return array;
    }

    public double[] NextDoubleArray(int size)
    {
        var array = new double[size];
        for (int i = 0; i < size; i++) array[i] = NextDouble();
        return array;
    }

    public string Next()
    {
        if (TokenQueue.Count == 0)
        {
            if (!StockTokens()) throw new InvalidOperationException();
        }
        return TokenQueue.Dequeue();
    }

    public bool HasNext()
    {
        if (TokenQueue.Count > 0)
            return true;
        return StockTokens();
    }
    static readonly char[] _separator = new[] { ' ' };
    private bool StockTokens()
    {
        while (true)
        {
            var line = Reader.ReadLine();
            if (line == null) return false;
            var tokens = line.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
            if (tokens.Length == 0) continue;
            foreach (var token in tokens)
                TokenQueue.Enqueue(token);
            return true;
        }
    }
}