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 Rust (1.42.0) (judge verdict: Accepted)

use proconio::*;
use std::collections::VecDeque;
use std::f64;

fn main() {
  input! {
    n: usize,
    a: [f64; n],
  }
  let mut deque = VecDeque::new();
  for i in 0..n {
    let points = vec![(a[i] - i as f64, 0.0)];
    let f = PiecewiseLinearFunction { 
      points, left_slope: -1.0, right_slope: 1.0
    };
    deque.push_back(f);
  }
  while deque.len() >= 2 {
    let f = deque.pop_front().unwrap();
    let g = deque.pop_front().unwrap();
    deque.push_back(f.add(&g));
  }
  let f = deque.pop_back().unwrap();
  let (x,y) = f.minimum();
  println!("{}", y.round() as i64);
}


#[derive(Clone,Debug)]
struct PiecewiseLinearFunction {
  points: Vec<(f64,f64)>,
  left_slope: f64,
  right_slope: f64,
}
// Basic Manipulations
impl PiecewiseLinearFunction {
  pub fn from_points(points: Vec<(f64,f64)>) -> Self {
    Self { points, left_slope: f64::NEG_INFINITY, right_slope: f64::INFINITY }
  }
  fn slope(&self, i: usize) -> f64 {
    if i == 0 {
      self.left_slope
    } else if i == self.points.len() {
      self.right_slope
    } else {
      let (x1,y1) = self.points[i-1];
      let (x2,y2) = self.points[i];
      (y2 - y1)/(x2 - x1)
    }
  }
  pub fn add(&self, other: &Self) -> Self {
    let mut points = vec![];
    let mut i = 0;
    let mut j = 0;
    loop { 
      let (x, y) = match (self.points.get(i), other.points.get(j)) {
        (Some(&(x1,y1)), Some(&(x2,y2))) => { 
          if x1 < x2 {
            i += 1;
            (x1, y1 + y2 + other.slope(j) * (x1 - x2))
          } else {
            j += 1;
            (x2, y2 + y1 + self.slope(i) * (x2 - x1))
          }
        },
        (Some(&(x1,y1)), None) => {
          i += 1;
          let &(x2,y2) = other.points.last().unwrap();
          (x1, y1 + y2 + other.slope(j) * (x1 - x2))
        },
        (None, Some(&(x2,y2))) => {
          j += 1;
          let &(x1,y1) = self.points.last().unwrap();
          (x2, y2 + y1 + self.slope(i) * (x2 - x1))
        },
        _ => { break; }
      };
      if y.is_infinite() { continue; }
      if let Some((x0,_)) = points.last() {
        if x0 + 1e-9 >= x { continue; }
      }
      points.push((x,y));
    }
    Self { 
      points, 
      left_slope: self.left_slope + other.left_slope, 
      right_slope: self.right_slope + other.right_slope,
    }
  }
  pub fn mul(&self, a: f64) -> Self {
    let points = self.points.iter().map(|&(x,y)| (x,a*y)).collect();
    Self { 
      points, 
      left_slope: a * self.left_slope,
      right_slope: a * self.right_slope,
    }
  }
  pub fn eval_at(&self, z: f64) -> f64 {
    if let Some(&(x,y)) = self.points.first() {
      if z < x { return y + self.left_slope * (z - x); }
    }
    if let Some(&(x,y)) = self.points.last() {
      if z > x { return y + self.right_slope * (z - x); }
    }
    match self.points.binary_search_by(|p| p.0.partial_cmp(&z).unwrap()) {
      Ok(k) => {
        return self.points[k].1;
      },
      Err(k) => {
        let (x,y) = self.points.get(k-1).unwrap();
        return y + self.slope(k) * (z - x)
      }
    }
  }
}

// Convex Manipulations
impl PiecewiseLinearFunction {
  fn conjugate(&self) -> Self {
    let mut points = vec![];
    let &(x,y) = self.points.first().unwrap();
    let left_slope = match self.left_slope {
      f64::NEG_INFINITY => x,
      c => {
        points.push((c, c*x-y));
        f64::NEG_INFINITY
      }
    };
    for i in 0..self.points.len()-1 {
      let &(x,y) = self.points.get(i).unwrap();
      let c = self.slope(i+1);
      points.push((c, x*c-y));
    }
    let &(x,y) = self.points.last().unwrap();
    let right_slope = match self.right_slope {
      f64::INFINITY => x,
      c => {
        points.push((c, c*x-y));
        f64::INFINITY
      }
    };
    Self { points, left_slope, right_slope }
  }
  fn closure(&self) -> Self {
    unimplemented!()
  }
  fn minimum(&self) -> (f64,f64) { // (x, f(x))
    let mut l = 0;
    let mut r = self.points.len() + 2;
    while l != r {
      let m = (l + r) / 2;
      if self.slope(m) < 0.0 { l = m + 1; }
      else                   { r = m; }
    }
    if l == 0 { 
      return (f64::NEG_INFINITY, f64::NEG_INFINITY);
    } else if l == self.points.len() + 2 {
      return (f64::INFINITY, f64::NEG_INFINITY);
    } else {
      return self.points[l-1];
    }
  }
}