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 C# (Mono-mcs 6.8.0.105) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace e
{
    class Program
    {
        static void Main(string[] args)
        {
            var humanCount = IOUtils.ReadInt();

            var heightDic = IOUtils.ReadLongs().Select((l, i) => new { no = i + 1, height = l }).ToDictionary(a => a.no, a => a.height);
            var orderedNos = heightDic.OrderBy(p => p.Value).Select(p => p.Key).ToList();
            var maxDiff = humanCount - 1;

            var res = 0;

            for (int i1 = 0; i1 < humanCount; i1++)
            {
                var no1 = orderedNos[i1];
                if (heightDic[no1] > maxDiff) break;

                for (int i2 = i1+1; i2 < humanCount; i2++)
                {
                    var no2 = orderedNos[i2];

                    var diff = Math.Abs(no1 - no2);
                    var hsum = heightDic[no1] + heightDic[no2];
                    if (diff == hsum)
                    {
                        res++;
                    }
                    if (maxDiff < hsum) break;
                }
            }

            Console.WriteLine(res);

        }
    }

    static class IOUtils
    {
        public static (int a, int b) Read2Ints()
        {
            var vals = ReadInts();
            return (vals[0], vals[1]);
        }
        public static (int a, int b, int c) Read3Ints()
        {
            var vals = ReadInts();
            return (vals[0], vals[1], vals[2]);
        }
        public static IEnumerable<int[]> ReadIntLines(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return ReadInts();
            }
        }
        public static IEnumerable<long[]> ReadLongLines(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return ReadLongs();
            }
        }
        public static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }
        public static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }
        public static ulong ReadUlong()
        {
            return ulong.Parse(Console.ReadLine());
        }
        public static int[] ReadInts()
        {
            return Console.ReadLine().Split(' ').Select(v => int.Parse(v)).ToArray();
        }
        public static long[] ReadLongs()
        {
            return Console.ReadLine().Split(' ').Select(v => long.Parse(v)).ToArray();
        }

        public static void WriteNums(params int[] nums)
        {
            Console.WriteLine(string.Join(" ", nums));
        }
    }


    static class MathUtils
    {
        /// <summary>
        /// 最大公約数
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        public static ulong Gcd(params ulong[] nums)
        {
            if (nums.Length == 0) return 0;
            if (nums.Length == 1) return nums.Single();

            var tmp = nums[0];
            var rest = new Queue<ulong>(nums.Skip(1));
            while (rest.Any())
            {
                tmp = gcd(tmp, rest.Dequeue());
            }
            return tmp;
        }
        private static ulong gcd(ulong a, ulong b)
        {
            while (true)
            {
                if (a % b == 0)
                {
                    return b;
                }
                else
                {
                    var x = a % b;
                    a = b;
                    b = x;
                }
            }
        }

        /// <summary>
        /// 最小公倍数
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        public static ulong Lcm(params ulong[] nums)
        {
            if (nums.Length == 0) return 0;
            if (nums.Length == 1) return nums.Single();

            var tmp = nums[0];
            var rest = new Queue<ulong>(nums.Skip(1));
            while (rest.Any())
            {
                tmp = lcm(tmp, rest.Dequeue());
            }
            return tmp;
        }

        private static ulong lcm(ulong a, ulong b)
        {
            return a / gcd(a, b) * b;
        }

        /// <summary>
        /// 素因数分解
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static IEnumerable<long> PrimeFactors(long n)
        {
            int i = 2;
            long tmp = n;

            while (i * i <= n)
            {
                if (tmp % i == 0)
                {
                    tmp /= i;
                    yield return i;
                }
                else
                {
                    i++;
                }
            }
            if (tmp != 1) yield return tmp;
        }

        /// <summary>
        /// 順列の数を返す
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static long P(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i);
            }
            return x;
        }

        /// <summary>
        /// 組み合わせの数を返す
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static long C(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i) / (i + 1);
            }
            return x;
        }

        /// <summary>
        /// 順列を列挙（幅優先）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static IEnumerable<T[]> EnumPermutations<T>(IReadOnlyList<T> src, int k)
        {
            if (src.Count < k || k <= 0) throw new ArgumentOutOfRangeException(nameof(k));

            var queue = new Queue<List<int>>(Enumerable.Range(0, src.Count).Select(i => new List<int>() { i }));
            while (queue.Any())
            {
                var indexes = queue.Dequeue();

                if (indexes.Count == k)
                {
                    yield return indexes.Select(i => src[i]).ToArray();
                    continue;
                }

                for (int index = 0; index < src.Count; index++)
                {
                    if (indexes.Contains(index))
                    {
                        continue;
                    }

                    var newIndexes = new List<int>(indexes);
                    newIndexes.Add(index);
                    queue.Enqueue(newIndexes);
                }
            }
        }
    }
}