• codeforces-1430E(树状数组+逆序对)


    codeforces1430E-String Reversal

    题目链接:http://codeforces.com/contest/1430/problem/E

    题目描述:

    给定一个字符串(abcd),将该字符串转换为它的反转字符串(dcba),只可以交换相邻的字符,问一共需要交换多少次

    思路:

    把字符串倒置,反转字符串的每个字符在原串中一定是优先采取最近的字符移动过来,很显然这种相邻交换字符的方式符合逆序对的计算,比如对于字符串"aabcd"的下标原本是(1,2,3,4,5),反转后的字符串"dcbaa"对应的下标就应该是(5,4,3,1,2),求出的逆序对数9就是交换次数。求逆序对采用了树状数组,维护原串中的字符下标的优先顺序采用了队列。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    using ll = long long;
    const ll N = 2e5+5;
    const double PI = acos(-1.0);
    #define Test ll tesnum;tesnum = read();while(tesnum--)
    
    ll read();
    ll C[N],n;
    int lowbit(int x){return x&(-x);}
    void update(int i,int v)
    {
        while(i<=n){
            C[i]+=v;
            i+=lowbit(i);
        }
    }
    int getsum(int i)
    {
        ll ans = 0;
        while(i){
            ans+=C[i];
            i-=lowbit(i);
        }
        return ans;
    }
    int main() {
        cin>>n;
        string s;
        cin>>s;
        queue<int> q[100];
        for(int i = 0; i < n; i++){
            q[s[i]-'a'].push(i+1);
        }
        reverse(s.begin(),s.end());
        ll ans = 0;
        for(int i = 0; i < n; i++){
            int id = q[s[i]-'a'].front();
            update(id,1);
            q[s[i]-'a'].pop();
            ans+=i+1-getsum(id);
        }
        cout<<ans<<endl;
        return "BT7274", NULL;
    }
    
    inline ll read() {
        ll hcy = 0, dia = 1;
        char boluo = getchar();
        while (!isdigit(boluo)) {
            if (boluo == '-')dia = -1;
            boluo = getchar();
        }
        while (isdigit(boluo)) {
            hcy = hcy * 10 + boluo - '0';
            boluo = getchar();
        }
        return hcy * dia;
    }
    
  • 相关阅读:
    消息队列介绍
    SpringBoot随笔-SpringBoot集成Druid
    Redis-Redis基本类型及使用Java操作
    信息安全
    计算机网络基础
    多媒体技术
    数据库基础
    程序设计基础
    计算机软件体系
    计算机硬件体系
  • 原文地址:https://www.cnblogs.com/cloudplankroader/p/13867019.html
Copyright © 2020-2023  润新知