Problem:
Score : 800 points

Problem Statement

You are given a string S consisting of lowercase English letters.
Determine whether we can turn S into a palindrome by repeating the operation of swapping two adjacent characters. If it is possible, find the minimum required number of operations.

Constraints

1 \leq |S| \leq 2 × 10^5

S consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

S

Output

If we cannot turn S into a palindrome, print -1. Otherwise, print the minimum required number of operations.

Sample Input 1

eel

Sample Output 1

1

We can turn S into a palindrome by the following operation:

Swap the 2-nd and 3-rd characters. S is now ele.

Sample Input 2

ataatmma

Sample Output 2

4

We can turn S into a palindrome by the following operation:

Swap the 5-th and 6-th characters. S is now ataamtma.

Swap the 4-th and 5-th characters. S is now atamatma.

Swap the 3-rd and 4-th characters. S is now atmaatma.

Swap the 2-nd and 3-rd characters. S is now amtaatma.

Sample Input 3

snuke

Sample Output 3

-1

We cannot turn S into a palindrome.

Solution in Rust (1.15.1) (judge verdict: Accepted)

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let s = sc
        .read::<String>()
        .chars()
        .map(|c| c as usize - 'a' as usize)
        .collect::<Vec<_>>();
    let n = s.len();
    let mut count = vec![0; 26];
    let mut pos = vec![0; n];
    for i in 0..n {
        pos[i] = count[s[i]];
        count[s[i]] += 1;
    }

    if count.iter().filter(|&&c| c % 2 == 1).count() > 1 {
        println!("-1");
        return;
    }

    let mut prefix = vec![];
    let mut center = None;
    let mut suffix = vec![];
    for i in 0..n {
        if pos[i] < count[s[i]] / 2 {
            prefix.push(i);
        } else if count[s[i]] % 2 == 1 && pos[i] * 2 + 1 == count[s[i]] {
            center = Some(i);
        } else {
            suffix.push(i);
        }
    }

    assert_eq!(prefix.len(), suffix.len());
    let mut initial_cost = 0;
    for (to, from) in prefix.iter().cloned().enumerate() {
        initial_cost += from - to;
    }
    if let Some(c) = center {
        initial_cost += suffix.iter().filter(|&&s| s < c).count();
    }

    let mut pos = vec![vec![]; 26];
    for (i, p) in prefix.into_iter().enumerate() {
        let s = s[p];
        pos[s].push(i);
    }
    for i in 0..26 {
        pos[i].reverse();
    }
    let mut a = vec![0; n / 2];
    for (from, s) in suffix.into_iter().map(|i| s[i]).rev().enumerate() {
        let to = pos[s].pop().unwrap();
        a[from] = to;
    }

    let n = a.len();
    let mut inv = vec![0; n];
    for i in 0..n {
        inv[a[i]] = i;
    }

    let mut cost = 0;
    let mut bit = fenwick_tree::FenwickTree::new(n, 0);
    for (to, from) in inv.into_iter().enumerate() {
        let cur = from + bit.sum(from, n);
        cost += cur - to;
        bit.add(from, 1);
    }

    println!("{}", initial_cost + cost);
}

pub mod fenwick_tree {
    /// `FenwickTree` is a data structure that can efficiently update elements
    /// and calculate prefix sums in a table of numbers.
    /// [https://en.wikipedia.org/wiki/Fenwick_tree](https://en.wikipedia.org/wiki/Fenwick_tree)
    pub struct FenwickTree<T> {
        n: usize,
        data: Vec<T>,
        init: T,
    }

    impl<T: Copy + ::std::ops::AddAssign + ::std::ops::Sub<Output = T>> FenwickTree<T> {
        /// Constructs a new `FenwickTree`. The size of `FenwickTree` should be specified by `size`.
        pub fn new(size: usize, init: T) -> FenwickTree<T> {
            FenwickTree {
                n: size + 1,
                data: vec![init; size + 1],
                init: init,
            }
        }

        pub fn add(&mut self, k: usize, value: T) {
            let mut x = k;
            while x < self.n {
                self.data[x] += value;
                x |= x + 1;
            }
        }

        /// Returns a sum of range `[l, r)`
        pub fn sum(&self, l: usize, r: usize) -> T {
            self.sum_one(r) - self.sum_one(l)
        }

        /// Returns a sum of range `[0, k)`
        pub fn sum_one(&self, k: usize) -> T {
            assert!(k < self.n, "k={} n={}", k, self.n);

            let mut result = self.init;
            let mut x = k as i32 - 1;
            while x >= 0 {
                result += self.data[x as usize];
                x = (x & (x + 1)) - 1;
            }

            result
        }
    }
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> IO<R, W> {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}