10
14
2015
0

2789: [Poi2012]Letters

2789: [Poi2012]Letters

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 236  Solved: 160
[Submit][Status][Discuss]

Description

给出两个长度相同且由大写英文字母组成的字符串A、B,保证A和B中每种字母出现的次数相同。

现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B。

 

Input

 

 

第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度。

第二行和第三行各一个长度为n的字符串,并且只包含大写英文字母。

 

 

Output

一个非负整数,表示最少的交换次数。

Sample Input

3
ABC
BCA

Sample Output

2

HINT

 

 


 

ABC -> BAC -> BCA

 

 

Source

    如果没有相同的字母那就是十分简单的逆序对。。然后考虑有相同字母的情况可以显然的发现目标串中第n次出现的字母对应当前串第n次出现的字母。。然后就变成傻逼题了。。。

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const ll N = 1000010;
char s[N],ss[N];
ll val[N],ans,n;
queue <int> q[26];
ll lowbit(ll x){return x&-x;}
void Insert(ll pos){for (ll i=pos;i<=n;i+=lowbit(i)) val[i]++;}
ll Query(ll pos){
	ll res = 0;
	for (ll i=pos;i;i-=lowbit(i)) res+=val[i];
	return res;
}
int main(){
	scanf("%d",&n);scanf("%s",s+1);
	for (ll i=1;i<=n;i++) q[s[i]-'A'].push(i);
	scanf("%s",ss+1);
	for (ll i=1;i<=n;i++){
		ll x = q[ss[i]-'A'].front();q[ss[i]-'A'].pop();
		Insert(n-x+1);ans+=Query(n-x);
	}
	printf("%lld",ans);
}
Category: BZOJ题解 | Tags: | Read Count: 536

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com