String Reversal
链接 : http://codeforces.com/problemset/problem/1430/E
参考于 : https://blog.csdn.net/bjfu170203101/article/details/109016222
标签: string *1900
思路:
字符串颠倒之后, 对于每个字母, 只要将原串中该字母从左到右的顺序依次放过来, 求一遍逆序对数量即可.
代码:
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define pb push_back
#define PII pair<int, int>
#define fi first
#define se second
#define inf 0x3f3f3f3f
const int N = 2e5 + 7;
int q[N], tmp[N];
int mp[26][N], cnt[26];
int used[26];
char a[N];
ll merge(int l, int r) {
if (l >= r) return 0;
int mid = l + r >> 1;
ll res = merge(l, mid) + merge(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r) {
if (q[i] <= q[j]) tmp[k++] = q[i++];
else {
res += mid - i + 1;
tmp[k++] = q[j++];
}
}
while (i <= mid) tmp[k++] = q[i++];
while (j <= r) tmp[k++] = q[j++];
for (int i = l, j = 0; i <= r; ++i, ++j) q[i] = tmp[j];
return res;
}
int main() {
IO;
int n, t, k = 0;
cin >> n;
for (int i = 0; i < n; ++i) {
char c;
cin >> c;
a[i] = c;
t = c - 'a';
mp[t][cnt[t]++] = i;
}
reverse(a, a + n);
for (int i = 0; i < n; ++i) {
int t = a[i] - 'a';
q[k++] = mp[t][used[t]++];
}
/*
for (int i = 0; i < n; ++i) cout << q[i] << " ";
cout << endl; */
cout << merge(0, n - 1) << endl;
return 0;
}