P3531 [POI2012]LIT-Letters

题目链接

第一眼看出来可能和求逆序对差不多。

主要是交换相邻字符这儿看出来是逆序对,就是有一点不一样,它排序的规则就是按字符串B的顺序。

CODE

#include 
#include 
#include 
#define ll long long
using namespace std;
const ll MAXN = 1e6 + 5;

inline ll read() {
    ll k = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        k = (k << 1) + (k << 3) + (ch & 15);
        ch = getchar();
    }
    if (f == -1) k = ~k + 1;
    return k;
}

inline void write(ll x) {
    if (x < 0)
        x = -x, putchar('-');
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}


ll tree[MAXN],n,ans,sign[30][MAXN],d[30],a[MAXN];
char s1[MAXN],s2[MAXN];

ll lowbit(ll x){
    return x & (-x);
}

void update(ll x,ll v){
    for (int i = x; i <= n ; i += lowbit(i)) tree[i] += v;
}

ll sum(ll x){
    ll res = 0;
    for (int i = x; i > 0 ; i -= lowbit(i)) res += tree[i];
    return res;
}

int main(){
    scanf("%d",&n);
    scanf("%s",s1);
    scanf("%s",s2);
    
    for(int i = 0 ; i <= n - 1; i++)    sign[s1[i] - 'A'][ ++ sign[s1[i]-'A'][0]] = i;
    for(int i = 0 ; i <= n - 1; i++)    a[i + 1] = sign[s2[i] - 'A'][ ++ d[s2[i]-'A']] + 1;
    
    for(int i = 1 ; i <= n ; i++){
        ans += sum(n) - sum(a[i] - 1);
        update(a[i],1);
    }
        
    write(ans);
    return 0;
}

你可能感兴趣的:(P3531 [POI2012]LIT-Letters)