Problem:
Score : 300 points

Problem Statement

You are given a sequence of length N: A_1, A_2, ..., A_N.
For each integer i between 1 and N (inclusive), answer the following question:

Find the maximum value among the N-1 elements other than A_i in the sequence.

Constraints

2 \leq N \leq 200000

1 \leq A_i \leq 200000

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1
:
A_N

Output

Print N lines. The i-th line (1 \leq i \leq N) should contain the maximum value among the N-1 elements other than A_i in the sequence.

Sample Input 1

3
1
4
3

Sample Output 1

4
3
4

The maximum value among the two elements other than A_1, that is, A_2 = 4 and A_3 = 3, is 4.

The maximum value among the two elements other than A_2, that is, A_1 = 1 and A_3 = 3, is 3.

The maximum value among the two elements other than A_3, that is, A_1 = 1 and A_2 = 4, is 4.

Sample Input 2

2
5
5

Sample Output 2

5
5

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::vec::Vec;
use std::cmp::*;

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace().map(|e| e.parse().ok().unwrap()).collect()
}

fn main() {
    let n: usize = read();

    let mut a: Vec<i64> = Vec::new();

    for _ in 0..n {
      let t: i64 = read();
      a.push(t);
    }

    let mut seg = SegmentTree::new_max(&a);

    for i in 0..n {
      println!("{}", max(seg.get_max(0, i), seg.get_max(i+1, n)));
    }
}


#[derive(Debug, PartialEq)]
struct SegmentTree {
  n: usize, //元の配列に一番近い2の冪乗を格納する
  tree: Vec<i64>,
}


// 区間の最小の値を求めるセグメント木
impl SegmentTree {

  // 元の配列をセグメント木で表現
  // 2^nが元の配列のサイズ以上になる最小のnをNとする
  // O(N)
  fn new_max(v: &Vec<i64>) -> SegmentTree {
    let mut n: usize = 1;
    // セグメント木の葉の要素数
    while n < v.len() { n *= 2; }

    // セグメント木を表現するベクター
    let mut tree = vec![std::i64::MIN; 2 * n - 1];  // 区間における最小値を求めるセグメント木に注意


    // 葉から順に値を格納していく
    // まず最下段に値を格納する
    for i in 0..v.len() { tree[i + n - 1] = v[i]; }

    // 最下段の次の下段から値を書くのしていく
    for i in (0..(n-1)).rev() {
      tree[i] = max(tree[2 * i + 1], tree[2 * i + 2]);  // 区間における最小値を求めるセグメント木に注意
    }

    SegmentTree { n: n, tree: tree }
  }


  // 元の配列のi番目の値が変更された時にセグメント木を更新
  // O(logN) Nは元の配列の長さを超える最小の2の冪乗
  fn update_max(&mut self, i: usize, val: i64) {
    // 最下段の葉を更新
    let mut m = i + self.n - 1;
    self.tree[m] = val;
    while m > 0 {
      m = (m - 1) / 2;
      self.tree[m] = max(self.tree[2 * m + 1], self.tree[2 * m + 2]); // 区間における最大値を求めるセグメント木に注意
    }
  }


  // 指定された区間の最大値を求める
  // 区間は半開区間[i, j)での最小値を求める
  // O(logN)
  fn get_max(&self, i: usize, j: usize) -> i64 {
    fn get_max_sub(t: &SegmentTree, a: usize, b: usize, k: usize, l: usize, r: usize) -> i64 {
      // 求めたい区間が今いるノードの対応する区間と交差していない
      if r <= a || b <= l { return std::i64::MIN; } // 区間における最小値を求めるセグメント木に注意

      // 求めたい区間が今いるノードの対応する区間を被覆してる
      if a <= l && r <= b { return t.tree[k]; }

      // 求めたい区間と今いるノードと対応している区間が交差してるとき
      // 子を探索する
      // 左の子の値
      let vl = get_max_sub(t, a, b, 2 * k + 1, l, (l + r) / 2);
      // 右のこの値
      let vr = get_max_sub(t, a, b, 2 * k + 2, (l + r) / 2, r);

      return max(vl, vr);
    }

    return get_max_sub(&self, i, j, 0, 0, self.n);
  }

}