Problem:
Score : 300 points

Problem Statement

You are given an integer sequence of length n, a_1, ..., a_n.
Let us consider performing the following n operations on an empty sequence b.

The i-th operation is as follows:

Append a_i to the end of b.

Reverse the order of the elements in b.

Find the sequence b obtained after these n operations.

Constraints

1 \leq n \leq 2\times 10^5

0 \leq a_i \leq 10^9

n and a_i are integers.

Input

Input is given from Standard Input in the following format:

n
a_1 a_2 ... a_n

Output

Print n integers in a line with spaces in between.
The i-th integer should be b_i.

Sample Input 1

4
1 2 3 4

Sample Output 1

4 2 1 3

After step 1 of the first operation, b becomes: 1.

After step 2 of the first operation, b becomes: 1.

After step 1 of the second operation, b becomes: 1, 2.

After step 2 of the second operation, b becomes: 2, 1.

After step 1 of the third operation, b becomes: 2, 1, 3.

After step 2 of the third operation, b becomes: 3, 1, 2.

After step 1 of the fourth operation, b becomes: 3, 1, 2, 4.

After step 2 of the fourth operation, b becomes: 4, 2, 1, 3.

Thus, the answer is 4 2 1 3.

Sample Input 2

3
1 2 3

Sample Output 2

3 1 2

As shown above in Sample Output 1, b becomes 3, 1, 2 after step 2 of the third operation. Thus, the answer is 3 1 2.

Sample Input 3

1
1000000000

Sample Output 3

1000000000

Sample Input 4

6
0 6 7 6 7 0

Sample Output 4

0 6 6 0 7 7

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Diagnostics;

public class Program
{
    public void Solve()
    {
        var sc = new Scanner();
        var deq = new Deque<int>();
        int N = sc.NextInt();
        int[] A = sc.IntArray();
        for (int i = 0; i < N; i++)
        {
            if (N % 2 == i % 2)
            {
                deq.PushBack(A[i]);
            }
            else
            {
                deq.PushFront(A[i]);
            }
        }

        Console.WriteLine(string.Join(" ", deq.Items));
    }

    public static void Main(string[] args)
    {
        new Program().Solve();
    }
}

class Scanner
{
    public Scanner()
    {
        _pos = 0;
        _line = new string[0];
    }

    const char Separator = ' ';
    private int _pos;
    private string[] _line;

    #region スペース区切りで取得

    public string Next()
    {
        if (_pos >= _line.Length)
        {
            _line = Console.ReadLine().Split(Separator);
            _pos = 0;
        }

        return _line[_pos++];
    }

    public int NextInt()
    {
        return int.Parse(Next());
    }

    public long NextLong()
    {
        return long.Parse(Next());
    }

    public double NextDouble()
    {
        return double.Parse(Next());
    }

    #endregion

    #region 型変換

    private int[] ToIntArray(string[] array)
    {
        var result = new int[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = int.Parse(array[i]);
        }

        return result;
    }

    private long[] ToLongArray(string[] array)
    {
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = long.Parse(array[i]);
        }

        return result;
    }

    private double[] ToDoubleArray(string[] array)
    {
        var result = new double[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = double.Parse(array[i]);
        }

        return result;
    }

    #endregion

    #region 配列取得

    public string[] Array()
    {
        if (_pos >= _line.Length)
            _line = Console.ReadLine().Split(Separator);

        _pos = _line.Length;
        return _line;
    }

    public int[] IntArray()
    {
        return ToIntArray(Array());
    }

    public long[] LongArray()
    {
        return ToLongArray(Array());
    }

    public double[] DoubleArray()
    {
        return ToDoubleArray(Array());
    }

    #endregion
}

#region Deque<T>

/// <summary>
/// 指定した同じ型のインスタンスの，先頭または末尾への要素の追加，削除が可能な可変サイズのコレクションを表します．
/// </summary>
/// <typeparam name="T"><see cref="Deque{T}"/> 内の要素の型を指定します．</typeparam>
public class Deque<T>
{
    int dx;
    T[] buf;
    int mask;

    /// <summary>
    ///<see cref="Deque{T}"/> に格納されている要素の数を取得します．
    /// </summary>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public int Count { get; private set; }

    /// <summary>
    /// 空であって，既定の初期容量を備えた <see cref="Deque{T}"/> クラスの新しいインスタンスを初期化します．
    /// </summary>
    public Deque() : this(8)
    {
    }

    /// <summary>
    /// 空であって，指定の初期容量を備えた <see cref="Deque{T}"/> クラスの新しいインスタンスを初期化します．
    /// </summary>
    /// <param name="capacity">作成したインスタンスが格納できる要素数の初期値．2 べきの値にしてください．</param>
    public Deque(int capacity)
    {
        Debug.Assert(capacity == (capacity & -capacity));
        mask = capacity - 1;
        buf = new T[capacity];
    }

    /// <summary>
    /// 指定したインデックスにある要素を取得または設定します．
    /// </summary>
    /// <param name="index">取得または設定する要素の，0-inexed での番号．</param>
    /// <returns>指定したインデックス位置にある要素</returns>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public T this[int index]
    {
        get
        {
            Debug.Assert(0 <= index && index < Count);
            return buf[(dx + index) & mask];
        }
        set
        {
            Debug.Assert(0 <= index && index < Count);
            buf[(dx + index) & mask] = value;
        }
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の先頭に要素を追加します．
    /// </summary>
    /// <param name="item">追加する要素</param>
    /// <remarks>この操作はならし計算量 O(1) で実行されます．</remarks>
    public void PushFront(T item)
    {
        if (Count == buf.Length) extend();
        dx = (dx + buf.Length - 1) & mask;
        buf[dx] = item;
        Count++;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の先頭から要素を削除し，返します．
    /// </summary>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public T PopFront()
    {
        Debug.Assert(Count > 0);
        var ret = buf[dx = (dx + 1) & mask];
        Count--;
        return ret;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の末尾に要素を追加します．
    /// </summary>
    /// <param name="item">追加する要素</param>
    /// <remarks>この操作はならし計算量 O(1) で実行されます．</remarks>
    public void PushBack(T item)
    {
        if (Count == buf.Length) extend();
        buf[(dx + Count++) & mask] = item;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の末尾から要素を削除し，返します．
    /// </summary>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public T PopBack()
    {
        Debug.Assert(Count > 0);
        var ret = buf[(dx + --Count) & mask];
        return ret;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の末尾の要素を返します．
    /// </summary>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public T Last()
    {
        Debug.Assert(Count > 0);
        return buf[(dx + Count - 1) & mask];
    }

    /// <summary>
    /// <see cref="Deque{T}"/> の先頭の要素を返します．
    /// </summary>
    /// <remarks>この操作は計算量 O(1) で実行されます．</remarks>
    public T First()
    {
        Debug.Assert(Count > 0);
        return buf[dx];
    }

    void extend()
    {
        var nbuf = new T[buf.Length * 2];
        for (int i = 0; i < buf.Length; i++)
            nbuf[i] = buf[(dx + i) & mask];
        mask = mask * 2 + 1;
        dx = 0;
        buf = nbuf;
    }

    /// <summary>
    /// デックを空にします．
    /// </summary>
    /// <remarks>この操作は O(1) で実行されます．</remarks>
    public void Clear()
    {
        Count = 0;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> 内に要素が存在するかどうかを調べます．
    /// </summary>
    /// <returns>要素が存在するならば true，そうでなければ false</returns>
    /// <remarks>この操作は O(1) で実行されます．</remarks>
    public bool Any()
    {
        return Count != 0;
    }

    /// <summary>
    /// 指定した位置に要素を挿入します．
    /// </summary>
    /// <param name="item">追加したい要素</param>
    /// <param name="index">追加したい位置の 0-indexed での番号</param>
    /// <remarks>この操作は最悪計算量 O(N) で実行されます．</remarks>
    public void Insert(int index, T item)
    {
        Debug.Assert(0 <= index && index <= Count);
        PushFront(item);
        for (int i = 0; i < index; i++)
            this[i] = this[i + 1];
        this[index] = item;
    }

    /// <summary>
    /// 指定した位置にある要素を削除し，返します．
    /// </summary>
    /// <param name="index">削除したい位置の 0-indexed での番号</param>
    /// <remarks>この操作は最悪計算量 O(N) で実行されます．</remarks>
    public T RemoveAt(int index)
    {
        Debug.Assert(0 <= index && index < Count);
        var ret = this[index];
        for (int i = index; i > 0; i--)
            this[i] = this[i - 1];
        PopFront();
        return ret;
    }

    /// <summary>
    /// <see cref="Deque{T}"/> 内にある要素の一覧を返します．
    /// </summary>
    /// <returns><see cref="Deque{T}"/> 内にある要素の一覧</returns>
    /// <remarks>この操作は O(N) で実行されます．</remarks>
    public T[] Items
    {
        get
        {
            var ret = new T[Count];
            for (int i = 0; i < Count; i++)
                ret[i] = this[i];
            return ret;
        }
    }
}

#endregion