[POI2012] 字母 Letters

RT。一道很有意思的BIT题。


首先给出两个串。

我们发现,在同一个串中相同的字符是不会交换的。

故,我们可以将一个串中的字符给予另一个串中的位置。

即:

a[i] = v[id(c)][nk[id(c)] ++]; 

这样,对于每个\(a_i\), 都有一个比他或大或小的位置,那么,类比权值计算逆序对即可。

#include <bits/stdc++.h>
using namespace std;
int read() {
	int f = 1, x = 0; char c = getchar();
	while(!isdigit(c)) {if(c == '-') f = -f; c = getchar();}
	while(isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();}
	return x * f;
}
const int N = 2e6 + 5; 
int n, m, p, q, t[N], a[N], bk[N];
int lowbit(int x) {
	return x & (-x);
}
void add(int x, int d) {
	for(int i = x; i <= n; i += lowbit(i)) 
		t[i] += d;
} 
int ask(int x) {
	int r = 0;
	for(int i = x; i ; i -= lowbit(i)) {
		r += t[i];
	}
	return r;
}
long long ans;
int id(char c) {return c - 64;}
vector <int> v[30]; 
int main() { 
	freopen("2281.in", "r", stdin);
	freopen("2281.out", "w", stdout);
	n = read();
	for(int i = 1; i <= n; i ++) {
		char c; cin >> c;
		v[id(c)].push_back(i);
	}
	for(int i = 1; i <= n; i ++) {
		char c; cin >> c;
		a[i] = v[id(c)][bk[id(c)] ++];
//		cout << a[i] << "\n";
	}
	for(int i = 1; i <= n; i ++) {
	//	cout << a[i] << "\n";
		ans += ask(n) - ask(a[i]);
		add(a[i], 1);
	}
	cout << ans << "\n";
	return 0;
}

posted @ 2021-10-02 14:42  永远_少年  阅读(46)  评论(0编辑  收藏  举报