「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;
}
标签:Letters,POI2012,字母,int,while,isdigit,串中,id,getchar 来源: https://www.cnblogs.com/LanternFestival/p/15361920.html