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.



Sample input:
eel


Sample output:
1

Submission status: Runtime Error

Solution code:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;

int main(){
    string S;
    cin >> S;
    int N = S.size();

    vector<vector<int>> cpos(26);
    for(int i=0;i<N;i++){
        cpos[S[i] - 'a'].push_back(i);
    }

    int odd_count = 0;
    for(int i=0;i<26;i++){
        if(cpos[i].size() % 2 != 0){
            odd_count++;
        }
    }
    if(odd_count > 1){
        assert(false);
        cout << -1 << endl;
        return 0;
    }

    int center = -1;
    vector<int> pair_to(N, -1);
    for(int i=0;i<26;i++){
        int n = cpos[i].size();
        for(int j=0;j<n/2;j++){
            int i1 = cpos[i][j];
            int i2 = cpos[i][n-1-j];
            pair_to[i1] = i2;
            pair_to[i2] = i1;
        }
        if(n % 2 == 1){
            assert(center == -1);
            center = cpos[i][n/2];
        }
    }
    for(int i=0;i<N;i++){
        assert(i == center || pair_to[i] != -1);
    }

    ll ans = 0;
    if(center != -1){
        ans += abs(center - N / 2);
    }

    vector<bool> used(N, false);
    queue<int> inc_que, eq_que;
    for(int i=0;i<N/2;i++){
        if(pair_to[i] != -1){
            if(pair_to[i] <= i || N - 1 - i <= pair_to[i]){
                inc_que.push(i);
            }else{
                eq_que.push(i);
            }
        }
        if(pair_to[N - 1 - i] != -1){
            if(pair_to[N - 1 - i] <= i || N - 1 - i <= pair_to[N - 1 - i]){
                inc_que.push(N - 1 - i);
            }else{
                eq_que.push(N - 1 - i);
            }
        }

        while(inc_que.size() > 0 && used[inc_que.front()]){
            inc_que.pop();
        }
        while(eq_que.size() > 0 && used[eq_que.front()]){
            eq_que.pop();
        }

        int i1 = -1;
        if(inc_que.size() > 0){
            i1 = inc_que.front();
            inc_que.pop();
        }else if(eq_que.size() > 0){
            i1 = eq_que.front();
            eq_que.pop();
        }
        assert(i1 != -1);

        int i2 = pair_to[i1];
        assert(!used[i2]);

        if(i1 > i2){
            swap(i1, i2);
        }
        // cout << i << " " << i1 << " " << i2 << endl;
        ans += abs(i - i1) + abs(N-1-i - i2);

        used[i1] = true;
        used[i2] = true;
    }

    cout << ans / 2 << endl;

    return 0;
}