有两个长度为 n 的由大写英文字母组成的字符串A, B,问最少需要多少次交换( 相邻两个交换 )才能使 A 变为 B ( 保证可以实现 )
首先的一个想法就是:要想总交换次数最小,A , B 中的相同字母要相距的距离最小( 贪心 )。然后就可以根据 A 中每个字母的位置, 把 B 对应成一个序列,求这个序列的逆序数。
/*
Author: JDD
PROG: bzoj2789.letters
DATE: 2015.11.03
*/
#include <cstdio>
#include <queue>
using namespace std;
const int MAX_N = 1000005;
#define low(x) (x & (-x))
int n, c[MAX_N];
queue<int> q[30];
void insert(int x, int p)
{
for(int i = x; i <= n; i += low(i))
c[i] += p;
}
int query(int x)
{
int ret = 0;
for(int i = x; i > 0; i -= low(i))
ret += c[i];
return ret;
}
void init()
{
scanf("%d", &n);
char s[MAX_N]; scanf("%s", s + 1);
for(int i = 1; i <= n; i ++)
q[s[i] - 'A' + 1].push(i);
}
void doit()
{
char s[MAX_N]; scanf("%s", s + 1);
long long ans = 0;
for(int i = 1; i <= n; i ++){
int p = q[s[i] - 'A' + 1].front(); q[s[i] - 'A' + 1].pop();
insert(p, 1);
ans += i - query(p);
}
printf("%lld\n", ans);
}
int main()
{
freopen("1.in", "r", stdin);
init(); doit();
return 0;
}