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 Rust (1.15.1) (judge verdict: Accepted)

use std::io;
use std::io::BufRead;

fn main() {
    let mut sc = Scanner::new(std::io::stdin());
    let n: usize = sc.next().unwrap();

    let mut a: Vec<i64> = vec![0; 1 << n];
    for i in 0..(1<<n) {
        a[i] = sc.next().unwrap();
    }
    let neg = 0usize.wrapping_sub(1);
    let mut dp: Vec<(usize, usize)> = vec![(neg, neg); 1<<n];
    dp[0] = (0, neg); // first, second
    for i in 1..(1<<n) {
        dp[i].0 = i;
        for j in 0..n {
            if (i & (1<<j)) > 0 {
                let i2 = i ^ (1<<j);
                for j in vec![dp[i2].0, dp[i2].1] {
                    if j == dp[i].0 || j == dp[i].1 || j == neg {
                        continue;
                    }
                    if a[j] > a[dp[i].0] {
                        dp[i].1 = dp[i].0;
                        dp[i].0 = j;
                    } else if dp[i].1 == neg || a[j] > a[dp[i].1] {
                        dp[i].1 = j;
                    }
                }
            }
        }
    }
    for k in 1..(1<<n) {
        let mut res = a[dp[k].0] + a[dp[k].1];
        for i in (0..n).rev() {
            let i2 = 1 << i;
            if k & i2 > 0 {
                let i3 = (k & (((1<<n) - 1) ^ (i2 - 1))) - 1;
                if i3 == 0 {
                    continue;
                }
                let v = a[dp[i3].0] + a[dp[i3].1];
                res = std::cmp::max(res, v);
            }
        }
        println!("{}", res);
    }
}

/// Scanner
///
/// # Example
/// ```
/// use contest::io::scanner;
/// let mut sc = scanner::Scanner::new("1 2 \n\n \r\t \n 3.5".as_bytes());
/// assert_eq!("1".to_string(), sc.next::<String>().unwrap());
/// assert_eq!(2, sc.next());
/// assert_eq!(3.5, sc.next());
/// assert_eq!(None, sc.next::<i32>());
/// ```

pub struct Scanner<R: io::Read> {
    br: io::BufReader<R>,
    // Read tokens are stored in reversed order per line.
    buf: Vec<String>,
}

impl<R: io::Read> Scanner<R> {
    pub fn new(r: R) -> Scanner<R> {
        Scanner {
            br: io::BufReader::new(r),
            buf: vec![],
        }
    }
    #[inline]
    pub fn next<T>(&mut self) -> Option<T>
        where T: std::str::FromStr,
              T::Err: std::fmt::Debug
    {
        self.next_string().map(|s| s.parse::<T>().expect("Parse failed: "))
    }
    fn next_string(&mut self) -> Option<String> {
        self.buf.pop().or_else(|| match self.update() {
            true => self.next_string(),
            false => None,
        })
    }
    #[inline]
    fn update(&mut self) -> bool {
        let mut s = String::new();
        let res = self.br.read_line(&mut s);
        match res.expect("I/O error.") {
            0 => false,
            _ => {
                self.buf = s.split_whitespace().map(|x| x.to_string()).rev().collect();
                true
            }
        }
    }
}