CodeForces - 1430E - String Reversal (树状数组)

You are given a string ss. You have to reverse it — that is, the first letter should become equal to the last letter before the reversal, the second letter should become equal to the second-to-last letter before the reversal — and so on. For example, if your goal is to reverse the string "abddea", you should get the string "aeddba". To accomplish your goal, you can swap the neighboring elements of the string.

Your task is to calculate the minimum number of swaps you have to perform to reverse the given string.

Input

The first line contains one integer nn (2≤n≤2000002≤n≤200000) — the length of ss.

The second line contains ss — a string consisting of nn lowercase Latin letters.

Output

Print one integer — the minimum number of swaps of neighboring elements you have to perform to reverse the string.

Examples

Input

5
aaaza

Output

2

Input

6
cbaabc

Output

0

Input

9
icpcsguru

Output

30

Note

In the first example, you have to swap the third and the fourth elements, so the string becomes "aazaa". Then you have to swap the second and the third elements, so the string becomes "azaaa". So, it is possible to reverse the string in two swaps.

Since the string in the second example is a palindrome, you don't have to do anything to reverse it.

题意:

每次操作只能交换相邻的两个字符,问最少几次操作将给定字符串反转过来

思路:

反转后的串的每个字符,选择离得最近的字符移动过来。用树状数组维护区间和,区间和表示的就是实现把一个字符移动到指定位置的移动步数,移动完一个字符后就不用再动了,所以在树状数组中把它原来位置的值减一

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;

int n, m;
int c[N];

int lowbit(int x) {
    return (-x) & x;
}

void add(int pos, int x) {
    while(pos <= n) {
        c[pos] += x;
        pos += lowbit(pos);
    }
}

int query(int pos) {
    int res = 0;
    while(pos > 0) {
        res += c[pos];
        pos -= lowbit(pos);
    }
    return res;
}

queue<int>q[30];

int main() {
    string s;
    while(~scanf("%d", &n)) {
        cin >> s;
        s = "#" + s;
        for(int i = 0; i < N; ++i) c[i] = 0;
        for(int i = 0; i < 30; ++i)
            while(!q[i].empty()) q[i].pop();
        for(int i = 1; i <= n; ++i) {
            q[s[i] - 'a'].push(i);
            add(i, 1);
        }
        ll ans = 0;
        for(int i = n; i >= 1; --i) {
            int tp = q[s[i] - 'a'].front();
            q[s[i] - 'a'].pop();
            ans += query(tp) - 1;
            add(tp, -1);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/109061910