Loading

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);
}
posted @ 2020-10-12 08:10  MQFLLY  阅读(168)  评论(0编辑  收藏  举报