zoukankan      html  css  js  c++  java
  • Codeforces Round 96 (Rated for Div. 2)E. String Reversal(树状数组求逆序对)

    传送门

    题目大意:有初始字符串和目标字符串,目标字符串是初始字符串的反转。

    每一步可交换相邻两个字符,求从初始字符串到目标字符串的最小步数。

    题解:

    若初始字符串为abcde,则反转后为edcba。用数组下标表示为初始字符串12345,反转后为54321。

    反转后的串的逆序对个数就是从初始串到目标串需要交换的相邻字符的个数。

    关键是如果初始字符串中有重复,如aaaza,反转后为azaaa。

    用数组下标表示为12345,反转后为14235更优。

    14235的逆序对个数就是12345交换相邻元素的步数。

    树状数组求逆序对

    写题解时突闻吹风机被导员收走的噩耗

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
     
    #define N 200002
     
    int n;
     
    char s[N];
    char t[N];
    int c[N];
    int tr[N];
    long long res;
    queue<int>a[30];
     
    int lowbit(int x)
    {
        return x&(-x);
    }
     
    void add(int x,int v)
    {
        for(int i=x;i<=n;i+=lowbit(i))
        {
            tr[i]+=v;
        }
    }
     
    int getsum(int x)
    {
        int tmp=0;
        for(int i=x;i>=1;i-=lowbit(i))
        {
            tmp+=tr[i];
        }
        return tmp;
    }
     
    int main()
    {
        scanf("%d",&n);
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
        {
            t[i]=s[n-i+1];
            a[s[i]-'a'+1].push(i);
        }
        for(int i=1;i<=n;i++)
        {
            c[i]=a[t[i]-'a'+1].front();
            a[t[i]-'a'+1].pop();
        }
        //   for(int i=1;i<=n;i++)
        //       cout<<c[i]<<" ";
        //  cout<<endl;
        for(int i=1;i<=n;i++)
        {
            add(c[i],1);
            //     cout<<getsum(c[i])<<":";
            res=res+i-getsum(c[i]);
        }
        cout<<res;
        return 0;
    }
  • 相关阅读:
    提交按钮变灰
    解析spring启动加载dubbo过程
    shiro的SecurityUtis
    spring集成shiro登陆流程(下)
    spring集成shiro登陆流程(上)
    shiro的DelegatingFilterProxy怎么找到ShiroFilterFactoryBean
    sql多表关联
    android常用控件
    android控件之EditText
    浅议iOS网络数据解析
  • 原文地址:https://www.cnblogs.com/zzyh/p/14873003.html
Copyright © 2011-2022 走看看