BZOJ 2789 Poi2012 Letters 树状数组

题目大意:给定两个字符串A和B,每次可以交换A中相邻两个字符,求最少交换多少次后A可以变成B

首先我们需要找到A中每个字符和B中每个字符的对应关系

容易发现,同样的字符一定是按顺序一一对应的,因为交换两个字符的相对位置是需要代价的poi

然后就是树状数组求逆序对了poi

水水更健康poi

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;
struct abcd{
	int to,next;
}table[M];
int head[128],tot;
int n,a[M];
char s1[M],s2[M];
void Add(int x,int y)
{
	table[++tot].to=y;
	table[tot].next=head[x];
	head[x]=tot;
}
namespace BIT{
	int c[M];
	void Update(int x)
	{
		for(;x<=n;x+=x&-x)
			c[x]++;
	}
	int Get_Ans(int x)
	{
		int re=0;
		for(;x;x-=x&-x)
			re+=c[x];
		return re;
	}
}
int main()
{
	using namespace BIT;
	int i;
	cin>>n;
	scanf("%s%s",s1+1,s2+1);
	for(i=1;i<=n;i++)
		Add(s1[i],i);
	for(i=n;i;i--)
	{
		a[i]=table[head[s2[i]]].to;
		head[s2[i]]=table[head[s2[i]]].next;
	}
	long long ans=0;
	for(i=n;i;i--)
	{
		ans+=Get_Ans(a[i]);
		Update(a[i]);
	}
	cout<<ans<<endl;
	return 0;
}


你可能感兴趣的:(树状数组,bzoj,BZOJ2789)