Educational CodeForces Round 96 E.String Reversal 贪心,树状数组
Educational CodeForces Round 96 E.String Reversal 贪心,树状数组
题意
给定一个字符串,每次只能通过相邻交换使得字符串翻转,问最少通过多少次交换。
\[2 \leq n \leq 2\times 10^5
\]
分析
朴素的思想是每次把第一个字符移到末尾。
贪心一点的想法是没必要把第一个移到末尾,字符集就那么大,只需要把最右边的移到末尾就可以了。
那么问题就在于那么计算要移动的次数,显然我们需要减掉到目标位置距离中已经被移走的数量,这个就可以用BIT高效完成。
代码
int n;
ll a[200005];
vector<ll> q[26];
void add(int x, int y) {
for (; x <= n; x += x & -x)
a[x] += y;
}
ll ask(int x) {
int res = 0;
for (; x; x -= x & -x)
res += a[x];
return res;
}
int main() {
n = readint();
string ss;
cin >> ss;
ll res = 0;
for (int i = 0; i < n; i++)
q[ss[i] - 'a'].push_back(i + 1);
for (int i = 0; i < n; i++) {
int pos = q[ss[i] - 'a'].back();
res += max(0ll, n - (ask(n) - ask(pos - 1)) - pos);
add(pos, 1);
q[ss[i] - 'a'].pop_back();
}
Put(res);
}