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)

// ---------- begin ModInt ----------
const MOD: u32 = 1_000_000_007;

#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> Self::Output {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> Self::Output {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> Self::Output {
        ModInt(if self.0 == 0 {0} else {MOD - self.0})
    }
}

impl std::fmt::Display for ModInt {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl std::str::FromStr for ModInt {
    type Err = std::num::ParseIntError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let val = s.parse::<u32>()?;
        Ok(ModInt::new(val))
    }
}

#[allow(dead_code)]
impl ModInt {
    pub fn new(n: u32) -> ModInt {
        ModInt(n % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        assert!(self.0 > 0);
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
#[allow(dead_code)]
struct Precalc {
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        let mut inv = vec![ModInt::one(); n + 1];
        let mut fact = vec![ModInt::one(); n + 1];
        let mut ifact = vec![ModInt::one(); n + 1];
        for i in 2..(n + 1) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        if k > n {
            return ModInt::zero();
        }
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
}
// ---------- end Precalc ----------

use std::io::Read;

// BB, RR があったら次の状態が一意に定まるはず
// BRBRB.. みたいな交互だったら次の状態は2通り、どちらも交互
// 上から塗ってマージしていくことができそう?

// 連続、交互
fn calc(h: &mut [u32]) -> (ModInt, ModInt) {
    let mut g = vec![];
    g.extend_from_slice(h);
    let d = h.iter().cloned().min().unwrap();
    for h in h.iter_mut() {
        *h -= d;
    }
    if *h.iter().max().unwrap() == 0 {
        let (x, y) = (ModInt(2).pow(h.len() as u32) - ModInt(2), ModInt(2).pow(d));
        return (x, y);
    }
    let mut a = vec![];
    let mut cnt = 0;
    let mut l = 0;
    while l < h.len() {
        if h[l] == 0 {
            cnt += 1;
            l += 1;
        } else {
            let mut r = l + 1;
            while r < h.len() && h[r] > 0 {
                r += 1;
            }
            a.push(calc(&mut h[l..r]));
            l = r;
        }
    }
    let mut x = ModInt::one();
    let mut y = ModInt(2);
    for a in a.iter() {
        x *= a.0 + a.1 * ModInt(2);
        y *= a.1;
    }
    let (x, y) = (x * ModInt(2).pow(cnt) - y, y);
    let y = y * ModInt(2).pow(d - 1);
    (x, y)
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap();
    let mut h: Vec<u32> = it.map(|s| s.parse().unwrap()).collect();
    if n == 1 {
        let ans = ModInt(2).pow(h[0]);
        println!("{}", ans);
        return;
    }
    let mut ans = ModInt::one();
    if h[0] > h[1] {
        ans *= ModInt(2).pow(h[0]- h[1]);
        h[0] = h[1];
    }
    if h[n - 1] > h[n - 2] {
        ans *= ModInt(2).pow(h[n - 1]- h[n - 2]);
        h[n - 1] = h[n - 2];
    }
    for i in 1..(n - 1) {
        let d = std::cmp::max(h[i - 1], h[i + 1]);
        if h[i] > d {
            ans *= ModInt(2).pow(h[i] - d);
            h[i] = d;
        }
    }
    let (a, b) = calc(&mut h);
    ans *= a + b;
    println!("{}", ans);
}

fn main() {
    run();
}