#![allow(dead_code)]
use crate::counter::Counter;
use crate::scanner::Scanner;
fn main() {
    let mut scan = Scanner::new();
    let n = scan.read::<usize>();
    let a = scan.readn::<i64>(n);
    let mut l = Counter::new();
    let mut r = Counter::new();
    for i in 0..n {
        l[i as i64 + a[i]] += 1;
        r[i as i64 - a[i]] += 1;
    }
    let mut ret = 0;
    for &x in l.keys() {
        ret += l[x] * r[x];
    }
    println!("{}", ret);
}
mod scanner {
    use std::io::{stdin, BufReader, Bytes, Read, Stdin};
    use std::str::FromStr;
    pub struct Scanner {
        buf: Bytes<BufReader<Stdin>>,
    }
    impl Scanner {
        pub fn new() -> Scanner {
            Scanner {
                buf: BufReader::new(stdin()).bytes(),
            }
        }
        pub fn read_next<T: FromStr>(&mut self) -> Option<T> {
            let token = self
                .buf
                .by_ref()
                .map(|c| c.unwrap() as char)
                .skip_while(|c| c.is_whitespace())
                .take_while(|c| !c.is_whitespace())
                .collect::<String>();
            token.parse::<T>().ok()
        }
        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_next().unwrap()
        }
        pub fn readn<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.read::<T>()).collect()
        }
        pub fn chars(&mut self) -> Vec<char> {
            self.read::<String>().chars().collect()
        }
    }
}
mod counter {
    use std::collections::HashMap;
    use std::hash::Hash;
    use std::ops::*;
    #[derive(Clone, Debug)]
    pub struct Counter<K: Eq + Hash> {
        pub cnt: HashMap<K, i64>,
        pub d: i64,
    }
    impl<K: Eq + Hash> Counter<K> {
        pub fn new() -> Counter<K> {
            Counter {
                cnt: HashMap::new(),
                d: 0,
            }
        }
        #[doc = " Remove key when the value <= 0"]
        pub fn dec(&mut self, key: K, delta: i64) {
            if self.peek(&key) - delta <= 0 {
                self.remove(&key);
            } else {
                *self.cnt.get_mut(&key).unwrap() -= delta;
            }
        }
        pub fn peek(&self, key: &K) -> i64 {
            *self.cnt.get(key).unwrap_or(&self.d)
        }
    }
    impl<K: Eq + Hash> Deref for Counter<K> {
        type Target = HashMap<K, i64>;
        fn deref(&self) -> &Self::Target {
            &self.cnt
        }
    }
    impl<K: Eq + Hash> DerefMut for Counter<K> {
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.cnt
        }
    }
    impl<K: Eq + Hash> Index<K> for Counter<K> {
        type Output = i64;
        fn index(&self, index: K) -> &Self::Output {
            self.cnt.get(&index).unwrap_or(&self.d)
        }
    }
    impl<K: Eq + Hash + Clone> IndexMut<K> for Counter<K> {
        fn index_mut(&mut self, index: K) -> &mut i64 {
            if !self.cnt.contains_key(&index) {
                self.cnt.insert(index.clone(), self.d);
            }
            self.cnt.get_mut(&index).unwrap()
        }
    }
    impl<K: Eq + Hash> std::iter::FromIterator<K> for Counter<K> {
        fn from_iter<T: IntoIterator<Item = K>>(iter: T) -> Self {
            let mut cnt = HashMap::new();
            for i in iter {
                *cnt.entry(i).or_insert(0) += 1;
            }
            Counter { cnt, d: 0 }
        }
    }
    impl<T: Eq + Hash + Clone> Add for Counter<T> {
        type Output = Counter<T>;
        fn add(self, other: Counter<T>) -> Counter<T> {
            let mut ret = Counter::new();
            for (k, v) in self.iter().chain(other.iter()) {
                ret[k.clone()] += *v;
            }
            ret
        }
    }
    impl<T: Eq + Hash + Clone> AddAssign for Counter<T> {
        fn add_assign(&mut self, other: Self) {
            *self = self.clone().add(other);
        }
    }
}



Measured memory_bytes: 14540