题目大意:给定两个字符串A和B,每次可以交换A中相邻两个字符,求最少交换多少次后A可以变成B
题解:如果串A,B中有若干个相同字母,应该把A中的1号和B中的1号配对(因为1号总是要配对,不如直接搞掉它)按照这样用B中位置对A重新编号。例如3 ABC BCA,编号为312,然后求逆序对就是答案了。
逆序对问题要求,这显然是一个二维偏序,一维天然有序,用树状数组维护第二维。
我的收获:类似某个noip题,贪心思想Orz
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int M=1000005;
int n,c[M];
long long ans;
char s[M];
queue<int> q[28];
int read() {char ch=getchar();while(ch<'A'||'Z'<ch) ch=getchar();return ch-'A'+1;}
void updata(int x,int v){for(int i=x;i<=n;i+=i&(-i)) c[i]+=v;}
int query(int x){int ret=0;for(int i=x;i>0;i-=i&(-i))ret+=c[i];return ret;}
void init()
{
cin>>n;
scanf("%s",s+1);
for(int i=1,t;i<=n;i++) q[t=read()].push(i);//用queue实现类似vector的功能
for(int i=1;i<=n;i++)
{
int t=s[i]-'A'+1;
int val=q[t].front();q[t].pop();
ans+=query(n)-query(val);//大于val的等于总数-小于等于val的
updata(val,1);
}
cout<<ans<<endl;
}
int main()
{
init();
return 0;
}