Problem:
Score : 1100 points

Problem Statement

Let us consider a grid of squares with 10^9 rows and N columns. Let (i, j) be the square at the i-th column (1 \leq i \leq N) from the left and j-th row (1 \leq j \leq 10^9) from the bottom.

Snuke has cut out some part of the grid so that, for each i = 1, 2, ..., N, the bottom-most h_i squares are remaining in the i-th column from the left.
Now, he will paint the remaining squares in red and blue.
Find the number of the ways to paint the squares so that the following condition is satisfied:

Every remaining square is painted either red or blue.

For all 1 \leq i \leq N-1 and 1 \leq j \leq min(h_i, h_{i+1})-1, there are exactly two squares painted red and two squares painted blue among the following four squares: (i, j), (i, j+1), (i+1, j) and (i+1, j+1).

Since the number of ways can be extremely large, print the count modulo 10^9+7.

Constraints

1 \leq N \leq 100

1 \leq h_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
h_1 h_2 ... h_N

Output

Print the number of the ways to paint the squares, modulo 10^9+7.

Sample Input 1

9
2 3 5 4 1 2 4 2 1

Sample Output 1

12800

One of the ways to paint the squares is shown below:

#
## #
### #
#### ###
#########

Sample Input 2

2
2 2

Sample Output 2

6

There are six ways to paint the squares, as follows:

## ## ## ## ## ##
## ## ## ## ## ##

Sample Input 3

5
2 1 2 1 2

Sample Output 3

256

Every way to paint the squares satisfies the condition.

Sample Input 4

9
27 18 28 18 28 45 90 45 23

Sample Output 4

844733013

Remember to print the number of ways modulo 10^9 + 7.

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

#[allow(unused_imports)]
use std::cmp::{min,max};
#[allow(unused_imports)]
use std::collections::BTreeMap;
#[allow(unused_imports)]
use std::ops::*;
#[allow(unused_imports)]
use std::collections::BinaryHeap;

#[allow(unused_macros)]
macro_rules! tf {
    ($c:expr, $t:expr, $f:expr) => {{
        if $c { $t } else { $f }
    }};
}

fn solve(xs: &[i64], prev_h: i64) -> (Mod,Mod) {
    let min_h = *xs.iter().min().unwrap();
    let mut cs = xs.split(|&x| x == min_h);
    let w = xs.iter().filter(|&x| *x == min_h).count();
    let mut c_dp: Vec<(Mod,Mod)> = vec![];
    while let Some(c) = cs.next() {
        if c.len() != 0 {
            c_dp.push(solve(c, min_h));
        }
    }
    let rect_h = min_h - prev_h;
    // 底が市松の場合
    // 長方形の天井から下に積んでいったあとで子を上に積む
    // 天井が市松なら同じor反対を下に積んでいくから2^rect_h, 子の底が市松ならrb..でもbr..でも子を積められる
    let dp1 = Mod(2).pow(rect_h as u64) * c_dp.iter().fold(Mod(1), |s,xi| s * xi.0);
    // 底が市松でない場合
    // 上に乗っかってる子に従って長方形の天井から下に積んでいくイメージ，天井が決まれば反転のみ1通り
    // 子が乗らない列は[rb..]^T, [br..]^Tもいける．
    // 子が乗っている列の天井は，子が市松ならrb..とbr..の2通り，それ以外は反転のみ1通り
    // 反転のみで下に積んだ市松のパターンはdp1でも数えているのでexclusive
    let dp2 = Mod(2).pow(w as u64) * c_dp.iter().fold(Mod(1), |s,xi| s * (Mod(2) * xi.0 + xi.1))
            - Mod(2) * c_dp.iter().fold(Mod(1), |s,xi| s * xi.0);
    (dp1,dp2)
}

fn main() {
    let _n = read_i64() as usize;
    let xs = read_vec_i64();
    let (dp1,dp2) = solve(&xs, 0);
    println!("{}", (dp1 + dp2).0);
}

const MOD : u64 = 1_000_000_007;
#[derive(Clone,Copy,PartialEq,Eq,PartialOrd,Ord)]
struct Mod (u64);
use std::ops::*;

impl Mod {
    fn pow(self, n: u64) -> Mod {
        if n == 0 {
            return Mod(1);
        }
        let t = self.pow(n/2);
        if n % 2 == 0 {
            t * t
        }
        else {
            t * t * self
        }
    }
}

impl Add for Mod {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        Mod((self.0 + rhs.0) % MOD)
    }
}

impl AddAssign for Mod {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}

impl Sub for Mod {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        Mod((self.0 + MOD - rhs.0 % MOD) % MOD)
    }
}

impl SubAssign for Mod {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}

impl Mul for Mod {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self::Output {
        Mod(self.0 % MOD * rhs.0 % MOD)
    }
}

impl Div for Mod {
    type Output = Self;
    fn div(self, rhs: Self) -> Self::Output {
        self * rhs.pow(MOD-2)
    }
}

#[allow(dead_code)]
fn read_line() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret.pop();
    return ret;
}

#[allow(dead_code)]
fn read_i64() -> i64 {
    let ss = read_line();
    return ss.parse::<i64>().unwrap();
}

#[allow(dead_code)]
fn read_vec_i64() -> Vec<i64> {
    let mut res = vec![];
    let ss = read_line();
    for ts in ss.split_whitespace() {
        let x = ts.parse::<i64>().unwrap();
        res.push(x);
    }
    return res;
}

use std::fmt::Display;
#[allow(dead_code)]
fn write_vec<T: Display>(xs: &Vec<T>) {
    if xs.len() == 0 {
        println!("");
        return;
    }
    print!("{}", xs[0]);
    for i in 1..xs.len() {
        print!(" {}", xs[i]);
    }
    println!("");
}