2789: [Poi2012]Letters

来源:互联网 发布:淘宝收货地址 编辑:程序博客网 时间:2024/06/05 14:14

题目链接

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

题解:如果串A,B中有若干个相同字母,应该把A中的1号和B中的1号配对(因为1号总是要配对,不如直接搞掉它)按照这样用B中位置对A重新编号。例如3 ABC BCA,编号为312,然后求逆序对就是答案了。

逆序对问题要求123,这显然是一个二维偏序,一维天然有序,用树状数组维护第二维。

我的收获:类似某个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;}
原创粉丝点击