Problem:
Score: 500 points

Problem Statement

You are the top spy of AtCoder Kingdom. To prevent the stolen secret from being handed to AlDebaran Kingdom, you have sneaked into the party where the transaction happens.

There are N attendees in the party, and they are given attendee numbers from 1 through N. The height of Attendee i is A_i.

According to an examination beforehand, you know that a pair of attendees satisfying the condition below will make the transaction.

The absolute difference of their attendee numbers is equal to the sum of their heights.

There are \frac{N(N-1)}{2} ways to choose two from the N attendees and make a pair. Among them, how many satisfy the condition above?

P.S.: We cannot let you know the secret.

Constraints

All values in input are integers.

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

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

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 \dots A_N

Output

Print the number of pairs satisfying the condition.

Sample Input 1

6
2 3 3 1 3 1

Sample Output 1

3

A_1 + A_4 = 3, so the pair of Attendee 1 and 4 satisfy the condition.

A_2 + A_6 = 4, so the pair of Attendee 2 and 6 satisfy the condition.

A_4 + A_6 = 2, so the pair of Attendee 4 and 6 satisfy the condition.

No other pair satisfies the condition, so you should print 3.

Sample Input 2

6
5 2 4 2 8 8

Sample Output 2

0

No pair satisfies the condition, so you should print 0.

Sample Input 3

32
3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5

Sample Output 3

22

Solution in JavaScript (Node.js 12.16.1) (judge verdict: Accepted)


let input = require("fs").readFileSync("/dev/stdin", "utf8")

function main() {
    const [N] = load()
    const A = load(N)

    const B = []
    for(let i = 0; i < N; i++) {
        B.push(A[i] + i)
    }

    const C = {}
    for(let j = 0; j < N; j++) {
        const val = j - A[j]
        if(false === val in C) C[val] = []
        C[val].push(j)
    }

    let result = 0
    for(let i = 0; i < N; i++) {
        const b = B[i]
        if(false === b in C) continue
        result += C[b].length
//         result += C[b].filter(j => j > i).length
    }

    return result
}

/*

入力値を読み込む
load(rows = 1, cols = 1, type = Number)

TruthyならYes, FalsyならNo
yesno(boolean) => String

数列の和
array_sum(numbers) => Number

対無限ループ安全装置
inifinite_loop_preventer(max = 1e5)

配列の中から最大値を返す
array_max(numbers, initial_value = null) => Number

配列の中から最小値を返す
array_min(numbers, initial_value = null) => Number

オブジェクトのスナップショットをconsole.logする
log_obj(value)

nを素因数分解 
math_prime_factors(n) => { 素数: n乗 }

2次元配列を作る
new_array_2d(x_len, y_len = 0, init_value = 0) => [[]]

最大公約数
gcd(a, b) => Number

最小公倍数
lcm(a,b) => Number

subsetはsetの部分集合である
check_if_superset(set, subset) => Boolean

和集合
set_union(a, b) => Set

積集合
set_intersection(a, b) => Set

対称差集合
set_symmetric_difference(a, b) => Set

差集合
set_difference(a, b) => Set

配列からc個取る組み合わせ全列挙
set_combinations(array, count) => [[]]

*/


let inputs = input.split(/[\s\n]/)
let inifinite_loop_prevent_counter = 0
let result = main()
console.log(result)

if(result === undefined) {
    console.warn("result is undefined")
}
// console.timeEnd()


// 入力値を読み込む
function load(rows = 1, cols = 1, type = Number) {
    const length = rows * cols
    let result = inputs.splice(0, length)

    if(type !== String) result = result.map(type)
    if(cols > 1) {
        const arrays = new Array(cols)
        for(let col = 0; col < cols; col++) {
            arrays[col] = new Array()
            for(let row = 0; row < rows; row++) {
                arrays[col].push(result[row * cols + col])
            }
        }
        result = arrays
    }

    return result
}

// TruthyならYes, FalsyならNo
function yesno(value) {
    return value ? 'Yes' : 'No'
}

// 数列の和
function array_sum(numbers) {
    return numbers.reduce((acc, cur) => acc + cur, 0)
}

// 対無限ループ安全装置
function inifinite_loop_preventer(max = 1e5) {
    inifinite_loop_prevent_counter++
    if(inifinite_loop_prevent_counter >= max) {
        throw new Error("Infinite loop")
    }
}

// 配列の中から最大値を返す
function array_max(numbers, initial_value = null) {
    let result = (initial_value === null) ? numbers[0] : initial_value
    for(const n of numbers) if(n > result) result = n
    return result
}

// 配列の中から最小値を返す
function array_min(numbers, initial_value = null) {
    let result = (initial_value === null) ? numbers[0] : initial_value
    for(const n of numbers) if(n < result) result = n
    return result
}

// オブジェクトのスナップショットをconsole.logする
function log_obj(value) {
    console.log(JSON.parse(JSON.stringify(value)))
}

// 素因数分解 { 素数: n乗 }
function math_prime_factors(n) {
    const result = {}

    for(let i = 2; i * i <= n; i++) {
        if(n % i === 0) {
            n /= i
            result[i] = 1
            
            while(n % i === 0) {
                n /= i
                result[i]++
            }
        }
    }

    if(n > 1) result[n] = 1

    return result
}

// 2次元配列を作る
function new_array_2d(x_len, y_len = 0, init_value = 0) {

    const array = new Array()
    for(let i = 0; i < x_len; i++) {
        const y = y_len ? new Array(y_len).fill(init_value) : new Array()
        array.push(y)
    }

    return array
}

// 最大公約数
function gcd(a, b) {
    if(b === 0) return a
    return gcd(b, a % b)
}

// 最小公倍数
function lcm(a,b) {
    const g = (n, m) => m ? g(m, n % m) : n
    return a * b / g(a, b)
}

// subsetはsetの部分集合である
function check_if_superset(set, subset) {
    for(let el of subset) {
        if(!set.has(el)) {
            return false
        }
    }
    return true
}

// 和集合
function set_union(a, b) {
    const result = new Set(a)
    for(const el of b) result.add(el)
    return result
}

// 積集合
function set_intersection(a, b) {
    let result = new Set()
    for(let el of b) {
        if(a.has(el)) {
            result.add(el)
        }
    }
    return result
}

// 対称差集合
function set_symmetric_difference(a, b) {
    let result = new Set(a)
    for(let el of b) {
        if(result.has(el)) {
            result.delete(el)
        } else {
            result.add(el)
        }
    }
    return result
}

// 差集合
function set_difference(a, b) {
    let result = new Set(a)
    for(let el of b) result.delete(el)
    return result
}

// 配列からc個取る組み合わせ全列挙
function set_combinations(array, count) {
    
    const result = []

    function _combi({ pre = [], rest }) {

        if(pre.length + rest.length < count) return

        if(pre.length < count) {
            for(let i = 0; i < rest.length; i++) {
                _combi({
                    pre: [...pre, rest[i]],
                    rest: rest.slice(0,i)
                })
            }
        } else {
            result.push(pre)
        }
    }

    _combi({ rest: array })

    return result
}

function math_permutation(n, r) {
    let res = 1
    for(let i = 0; i < r; i++) {
        res *= n - i
    }
    return res
}

function math_combination(n, r) {
    return math_permutation(n, r) / math_permutation(r, r)
}