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 C++14 (Clang 3.8.0) (judge verdict: Wrong Answer)

#include<algorithm>
#include<cmath>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<set>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
#include<vector>
using uint = unsigned int;
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include"rprint2.hpp"
#include"debug_deque.hpp"
// #define vector DebugDeque
#else
#define FUNC(name) template <ostream& out = cout, class... T> void name(T&&...){ }
FUNC(prints) FUNC(printe) FUNC(printw) FUNC(printew) FUNC(printb) FUNC(printd) FUNC(printde);
#endif

template <class V = ll, bool max = false, V defval = 0>
struct SegTree{
    SegTree *l, *r;
    int left, right;
    V value = defval;
    SegTree(int size):SegTree(0, size - 1){ }
    SegTree(int st, int lt): left(st), right(lt){
        if(left == right){
            l = r = nullptr;
        }else{
            l = new SegTree(left, (right - left) / 2 + left);
            r = new SegTree((right - left) / 2 + left + 1, right);
        }
    }
    void init(vector<V>& data){
        if(left == right){
            value = data[left];
        }else{
            l -> init(data);
            r -> init(data);
        }
    }
    void add(int st, int lt, V val){
        if(right < st || lt < left){ return; }
        if(st <= left && right <= lt){
            value += val;
        }else if(l){
            l -> add(st, lt, val);
            r -> add(st, lt, val);
        }
    }
	V getVal(int idx){
        if(right < idx || idx < left){ return 0; }
        return value + (l ? l->getVal(idx) : 0) + (r ? r->getVal(idx) : 0);
	}
};


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    string s; cin >> s;
    vector<vector<int>> cs(255, vector<int>());
    for(size_t i = 0; i < s.size(); i++){
        cs[s[i]].push_back(i);
    }
    // int ans = 0;
    // int r = s.size() - 1;
    // int odds = 0;
    // for(char c = 'a'; c <= 'z'; c++){
    //     if(cs[c].empty()){ continue; }
    //     // printd(cs[c]);
    //     odds += cs[c].size() & 1;
    //     for(size_t i = 0; i < cs[c].size() / 2; i++){
    //         ans += abs(cs[c][i] - (r - cs[c][cs[c].size() - 1 - i]));
    //     }
    //     if(odds){
    //         ans += abs(cs[c][cs[c].size() / 2] - (int)s.size() / 2);
    //     }
    // }
    // printd(ans);
    // cout << (odds > 1 ? -1 : (ans) / 2) << '\n';
    int r = s.size() - 1;
    int n = s.size();
    SegTree<int> st(n);
    vector<int> v(n);
    iota(v.begin(), v.end(), 0);
    st.init(v);
    vector<int> is(255);
    int odds = 0;
    int ans = 0;
    for(int i = 0; i < n; i++){
        char c = s[i];
        odds += is[c] == cs[c].size() / 2 && cs[c].size() & 1;
        if(odds > 1){
            cout << -1 << '\n';
            return 0;
        }
        int i1 = cs[c][is[c]], i2 = cs[c][cs[c].size() - 1 - is[c]];
        is[c]++;
        int p1 = st.getVal(i1), p2 = st.getVal(i2);
        if(i1 > i2){
        }else if(odds && i1 == i2){
            if(p1 < (int)s.size() / 2){
                printd(c, i, p1, (int)s.size() / 2);
                ans += abs(p1 - (int)s.size() / 2);
            }
        }else{
            ans += abs(p1 - odds - (r - p2));
            st.add(i2, r, -1);
            // printd(c, i, p1, p2, abs(p1 - (r - p2)));
        }
    }
    cout << ans << '\n';
}