Problem:
Score : 700 points

Problem Statement

There is an integer sequence of length 2^N: A_0, A_1, ..., A_{2^N-1}. (Note that the sequence is 0-indexed.)

For every integer K satisfying 1 \leq K \leq 2^N-1, solve the following problem:

Let i and j be integers. Find the maximum value of A_i + A_j where 0 \leq i < j \leq 2^N-1 and (i or j) \leq K.
Here, or denotes the bitwise OR.

Constraints

1 \leq N \leq 18

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_0 A_1 ... A_{2^N-1}

Output

Print 2^N-1 lines.
In the i-th line, print the answer of the problem above for K=i.

Sample Input 1

2
1 2 3 1

Sample Output 1

3
4
5

For K=1, the only possible pair of i and j is (i,j)=(0,1), so the answer is A_0+A_1=1+2=3.

For K=2, the possible pairs of i and j are (i,j)=(0,1),(0,2).
When (i,j)=(0,2), A_i+A_j=1+3=4. This is the maximum value, so the answer is 4.

For K=3, the possible pairs of i and j are (i,j)=(0,1),(0,2),(0,3),(1,2),(1,3),(2,3) .
When (i,j)=(1,2), A_i+A_j=2+3=5. This is the maximum value, so the answer is 5.

Sample Input 2

3
10 71 84 33 6 47 23 25

Sample Output 2

81
94
155
155
155
155
155

Sample Input 3

4
75 26 45 72 81 47 97 97 2 2 25 82 84 17 56 32

Sample Output 3

101
120
147
156
156
178
194
194
194
194
194
194
194
194
194

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Runtime Error)

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
class Main{

    static class RMQ{
        long data[][];
        int N;
        
        RMQ(int n){
            N=1;
            while(N<n)N*=2;
            data = new long[N*2][2];
        }

        void set(int x, long d){
            x += N;
            data[x][0]=d;
            data[x][1]=0;
            long[] tmp = new long[2];
            for(x/=2;x>0;x/=2){
                tmp[0]=data[x*2][0];
                tmp[1]=data[x*2][1];
                tmp[2]=data[x*2+1][0];
                tmp[3]=data[x*2+1][1];
                Arrays.sort(tmp);
                data[x][0]=tmp[3];
                data[x][1]=tmp[2];
            }
        }

        long[] get(int l, int r, int k, int a, int b){
            if(l<=a&&b<=r)return data[k];
            if(r<=a||b<=l)return new long[2];

            long[] tmp = new long[4];
            long[] d1 = get(l, r, 2*k, a, (a+b)/2);
            long[] d2 = get(l, r, 2*k+1, (a+b)/2, b);
            tmp[0]=d1[0];
            tmp[1]=d1[1];
            tmp[2]=d2[0];
            tmp[3]=d2[1];
            Arrays.sort(tmp);
            d1[0]=tmp[3];d1[1]=tmp[2];
            return d1;
        }

        long get(int l, int r){
            long[] res = get(l, r, 1, 0, N);
            return res[0]+res[1];
        }
    }

    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        RMQ rmq = new RMQ((1<<N));
        long[] a = new long[(1<<N)];
        for(int i=0;i<(1<<N);++i)a[i]=scan.nextLong();
        for(int i=0;i<(1<<N);++i)rmq.set(i, a[i]);
        PrintWriter out = new PrintWriter(System.out);
        for(int K=1;K<(1<<N);++K){
            long res = 0;
            int base = 0;
            for(int j=N;j>=0;--j){
                if(((K>>j)&1)==1){
                    res = Math.max(res, rmq.get(base, base+(1<<j)));
                    base += (1<<j);
                }
            }
            long max1=-1;
            long max2=-1;
            for(int j=K;j>=0;--j){
                j&=K;
                if(a[j]>max1){
                    max2=max1;
                    max1=a[j];
                }else if(a[j]>max2){
                    max2=a[j];
                }
            }
            out.println(Math.max(res, max1+max2));
        }
        out.flush();out.close();
    }
}