BZOJ 2789 Poi 2012 Letters 樹狀數組 逆序對

給出兩個長度相同且由大寫英文字母組成的字符串 AB ,保證 AB 中每種字母出現的次數相同。
現在每次可以交換 A 中相鄰兩個字符,求最少需要交換多少次可以使得 A 變成 B

求逆序對
每種字母的相對位置一定不會改變,也就是說每種字母在一開始就已經確定了要對應移到哪一位了,這就相當於求序列逆序對數,和火柴排隊差不多
這題我還想了10MIN……

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
#define lowbit(x)((x)&(-x))
#define N 1000000+1
using namespace std;

int a[N];

void updata(int x,int num)
{
    while(x<N)
    {
        a[x]+= num;
        x+=lowbit(x);
    }
}

int ask(int x)
{
    int num = 0;
    while(x)
    {
        num += a[x];
        x -= lowbit(x);
    }   
    return num;
}

char str[N];
vector<int> v[27];
int last[27];
int tmp[N];

int main()
{
    int n;
    cin>>n;
    scanf("%s",str+1);
    for(int i=1;i<=n;++i)
        v[str[i]-'A'].push_back(i);
    scanf("%s",str+1);
    for(int i=1;i<=n;++i)
    {
        tmp[i] = v[str[i]-'A'][last[str[i]-'A']];
        last[str[i]-'A']++;
    }
    long long ans = 0;
    for(int i=1;i<=n;++i)
    {
        ans += ask(N-1)-ask(tmp[i]);
        updata(tmp[i],1);
    }
    cout<<ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章