Problem:
Score : 700 points

Problem Statement

There is a sequence X of length N, where every element is initially 0. Let X_i denote the i-th element of X.

You are given a sequence A of length N. The i-th element of A is A_i. Determine if we can make X equal to A by repeating the operation below. If we can, find the minimum number of operations required.

Choose an integer i such that 1\leq i\leq N-1. Replace the value of X_{i+1} with the value of X_i plus 1.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq A_i \leq 10^9(1\leq i\leq N)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1
:
A_N

Output

If we can make X equal to A by repeating the operation, print the minimum number of operations required. If we cannot, print -1.

Sample Input 1

4
0
1
1
2

Sample Output 1

3

We can make X equal to A as follows:

Choose i=2. X becomes (0,0,1,0).

Choose i=1. X becomes (0,1,1,0).

Choose i=3. X becomes (0,1,1,2).

Sample Input 2

3
1
2
1

Sample Output 2

-1

Sample Input 3

9
0
1
1
0
1
2
2
1
2

Sample Output 3

8

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

#![allow(non_snake_case)]

use std::io::{stdin, Read};
use std::str::FromStr;
fn read_option<T: FromStr>() -> Option<T> {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok()
}
fn read<T: FromStr>() -> T {
    let opt = read_option();
    opt.expect("failed to parse token")
}

use std::cmp::Ordering;

#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Rev<T>(pub T);

impl<T: PartialOrd> PartialOrd for Rev<T> {
    fn partial_cmp(&self, other: &Rev<T>) -> Option<Ordering> {
        other.0.partial_cmp(&self.0)
    }
}

impl<T: Ord> Ord for Rev<T> {
    fn cmp(&self, other: &Rev<T>) -> Ordering {
        other.0.cmp(&self.0)
    }
}

fn main() {
    let N: usize = read();
    let vec = (0..N).map(|_| read::<usize>()).collect::<Vec<usize>>();
    if vec[0] != 0 {
        println!("-1");
        return;
    }
    for v in vec.windows(2) {
        let before = v[0];
        let now = v[1];
        if now > before + 1 {
            println!("-1");
            return;
        }
    }
    let mut ans = 0;
    use std::collections::{BinaryHeap, HashSet};
    let mut set = HashSet::new();
    let mut heap: BinaryHeap<Rev<usize>> = BinaryHeap::new();

    for (minus_val, &v) in vec.iter().rev().enumerate() {
        if v == 0 {
            set.clear();
            heap.clear();
            continue;
        }
        let mut remove_flag = false;
        if let Some(min) = heap.peek() {
            let Rev(min) = *min;
            if (min - minus_val) == 0 {
                remove_flag = true;
            }
        }
        if remove_flag {
            let min = heap.pop().unwrap().0;
            set.remove(&min);
        }
        if !set.contains(&(v + minus_val)) {
            set.insert(v + minus_val);
            heap.push(Rev(v + minus_val));
        }
        ans += set.len();
    }
    println!("{}", ans);
}