Problem:
Score : 300 points

Problem Statement

Snuke has an integer sequence A of length N.

He will freely choose an integer b.
Here, he will get sad if A_i and b+i are far from each other.
More specifically, the sadness of Snuke is calculated as follows:

abs(A_1 - (b+1)) + abs(A_2 - (b+2)) + ... + abs(A_N - (b+N))

Here, abs(x) is a function that returns the absolute value of x.

Find the minimum possible sadness of Snuke.

Constraints

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

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the minimum possible sadness of Snuke.

Sample Input 1

5
2 2 3 5 5

Sample Output 1

2

If we choose b=0, the sadness of Snuke would be abs(2-(0+1))+abs(2-(0+2))+abs(3-(0+3))+abs(5-(0+4))+abs(5-(0+5))=2.
Any choice of b does not make the sadness of Snuke less than 2, so the answer is 2.

Sample Input 2

9
1 2 3 4 5 6 7 8 9

Sample Output 2

0

Sample Input 3

6
6 5 4 3 2 1

Sample Output 3

18

Sample Input 4

7
1 1 1 1 2 3 4

Sample Output 4

6

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text;

public class Program
{

    public void Proc()
    {
        int inputCount = int.Parse(Reader.ReadLine());
        this.Items = Reader.ReadLine().Split(' ').Select(a => long.Parse(a)).ToArray();

        long minItem = Items.Min();
        long maxItem = Items.Max();

        long minB = 1000000000 * -2;
        long maxB = 1000000000 * 2;

        long b = GetAns(minB, maxB);
        long ans = GetCalc(b);
        Console.WriteLine(ans);

    }

    private long GetAns(long min, long max) {
        if(max-min <= 2) {
            long tmp1 = GetCalc(min);
            long tmp2 = GetCalc((max + min) / 2);
            long tmp3 = GetCalc(max);

            long tmp4 = new long[] { tmp1, tmp2, tmp3 }.Min();
            if(tmp1 == tmp4) {
                return min;
            } else if(tmp2 == tmp4) {
                return (max + min) / 2;
            } else {
                return max;
            }
        }

        long mid1 = min + ((max - min) / 3);
        long mid2 = max - ((max - min) / 3);

        long valMin = GetCalc(min);
        long valMid1 = GetCalc(mid1);
        long valMid2 = GetCalc(mid2);
        long valMax = GetCalc(max);

        long minVal = new long[] { valMin, valMid1, valMid2, valMax }.Min();

        if(valMin == minVal) {
            return GetAns(min, mid1);
        } else if(valMid1 == minVal) {
            return GetAns(min, mid2);
        } else if(valMid2 == minVal) {
            return GetAns(mid1, max);
        } else {
            return GetAns(mid2, max);
        }
    }

    private long GetCalc(long target) {
        if(dic.ContainsKey(target)) {
            return dic[target];
        }

        long num = 0;
        for (int i = 1; i <= Items.Length; i++) {
            num += Math.Abs(Items[i - 1] - (i + target));
        }
        dic[target] = num;
        return num;
    }

    private Dictionary<long, long> dic = new Dictionary<long, long>();
    private long[] Items;





    public class Reader
    {
        static StringReader sr;
        public static bool IsDebug = false;
        public static string ReadLine()
        {
            if (IsDebug)
            {
                if (sr == null)
                {
                    sr = new StringReader(InputText.Trim());
                }
                return sr.ReadLine();
            }
            else
            {
                return Console.ReadLine();
            }
        }
        private static string InputText = @"



1
10




";
    }

    public static void Main(string[] args)
    {
#if DEBUG
        Reader.IsDebug = true;
#endif
        Program prg = new Program();
        prg.Proc();
    }
}