巧用队列+树状数组求逆序对
1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N = 2e5 + 10;
5 ll pos[N], t[N];
6 int n;
7
8 inline ll lowbit(ll x){
9 return x & -x;
10 }
11
12 inline void add(ll x, ll val)
13 {
14 for(int i = x ; i <= n ; i += lowbit(i)){
15 t[i] += val;
16 }
17 }
18
19 inline int query(ll x)
20 {
21 ll ans = 0;
22 for(ll i = x ; i > 0 ; i -= lowbit(i)){
23 ans += t[i];
24 }
25 return ans;
26 }
27
28 int main(){
29 cin >> n;
30 string s; cin >> s;
31 queue<int> q[30];
32 for(int i = 0 ; i < n ; i++){
33 q[s[i] - 'a' + 1].push(i + 1);
34 }
35 for(int i = 1 ; i <= n ; i++){
36 int now = s[n - i] - 'a' + 1;
37 pos[i] = q[now].front();
38 q[now].pop();
39 }
40 ll res = 0;
41 add(pos[1], 1);
42 for(int i = 2 ; i <= n ; i++){
43 add(pos[i], 1);
44 res += query(n) - query(pos[i]);
45 }
46 cout << res << endl;
47
48 return 0;
49 }