• [CF1430E] String Reversal


    Description

    给定一个字符串 (s),求至少对 (s) 进行多少次相邻字符交换操作才能使得 (s) 变成 (s) 的翻转串。

    Solution

    如果将整个交换过程看做一个置换,显然最少的相邻交换次数等于置换的逆序对个数。

    那么我们将同一种字符在正序和倒序串中的出现位置都记录下来,然后顺序匹配即可。

    这样就可以算出一个排列,我们只需要计算这个排列的逆序对数即可。求逆序对数直接树状数组即可,倒序扫描整个置换,把这个数后面比它小的数的数目加入答案即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int M = 205;
    int n;
    string str;
    
    struct BinaryIndexTree 
    {
        int size;
        vector <int> a;
    
        BinaryIndexTree(int n)
        {
            size=n;
            a.resize(n+2);
        }
    
        int lowbit(int x)
        {
            return x&(-x);
        }
    
        void Add(int i)
        {
            while(i<=size)
            {
                a[i]++;
                i+=lowbit(i);
            }
        }
    
        int sum(int i)
        {
            int ans=0;
            while(i>0)
            {
                ans+=a[i];
                i-=lowbit(i);
            }
            return ans;
        }
    
        int Sum(int l,int r)
        {
            return sum(r)-sum(l-1);
        }
    };
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n>>str;
    
    
        vector <int> vec_pos_seq[M],vec_pos_rev[M];
    
        for(int i=0;i<str.length();i++)
        {
            vec_pos_seq[str[i]].push_back(i);
            vec_pos_rev[str[i]].push_back(str.length()-i-1);
        }
    
        for(char c='a';c<='z';c++)
        {
            sort(vec_pos_seq[c].begin(),vec_pos_seq[c].end());
            sort(vec_pos_rev[c].begin(),vec_pos_rev[c].end());
        }
        vector <int> p(n+2);
    
        for(char c='a';c<='z';c++)
        {
            int tot=vec_pos_seq[c].size();
            for(int i=0;i<tot;i++)
            {
                p[vec_pos_seq[c][i]+1]=vec_pos_rev[c][i]+1;
            }
        }
    
    
        int ans=0;
        BinaryIndexTree bit(n);
        for(int i=n;i>=1;i--)
        {
            ans+=bit.Sum(1,p[i]);
            bit.Add(p[i]);
        }
    
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    使用VisualStudio2015开发QT项目
    界面控件
    SmartGit 试用过期
    视图和模型变换
    模型变换和视图变换
    一元二次方程
    论cudnn与cuda之间的关系,和实际例子测试。
    在Ubuntu 18.04上安装Tensorflow
    ubuntu14.04安装CUDA8.0
    Windows10系统远程桌面连接出现卡顿如何解决
  • 原文地址:https://www.cnblogs.com/mollnn/p/14073223.html
Copyright © 2020-2023  润新知