10.07逆序对

Description

某正教授级特级教师获得了一段古老的文字,全部由 26 个大写英文字母组成。他产生了一个疯狂的想法,即想把这段文字中所有字母按 A 到 Z 的顺序排序,即所有 A 放在开头,然后跟着所有 B,再是所有 C,最后是所有 Z。比如原字符串为“HELLOWORLD”,排序后应变为“DEHLLLOORW”。但是特教毕竟领着国务院的特殊津贴,于是他还有一个要求,即排序时每次只能交换相邻两个字母。现在他想知道最少交换多少次能完成排序?

Input

仅一行,包含一个仅含大写字母的长度为 L 的字符串(注意L不输入)

Output

共一行,包含一个整数表示最少交换次数。

Sample Input

LSDSL

Sample Output

4

Hint

样例2输入
HELLOWORLD
样例2输出 
16
【数据范围】
对于 50%的数据,1 <= L<= 2000 ;
对于 100%的数据,1<=L<= 2 *10^6 。
 
 
 
 
SB逆序对数组开小炸成50分。。。。
算了题解就是逆序对
5555TAT我的50分啊太丢人了。。。。
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 long long ans=0,a[2000005],n,c[1000005];
 7 long long max0;
 8 long long lowbit(long long x){
 9     return x&(-x);
10 }
11 void add(long long x,long long v){
12     while(x<=max0){
13         c[x]+=v;
14         x+=lowbit(x);
15     }
16 }
17 long long query(long long x){
18     long long ans=0;
19     while(x){
20         ans+=c[x];
21         x-=lowbit(x);
22     }
23     return ans;
24 }
25 int main(){
26 //    freopen("swapping.in","r",stdin);
27 //    freopen("swapping.out","w",stdout);
28     string l;
29     cin>>l;
30     n=l.size();
31     for(long long i=0;i<n;i++){
32         a[i+1]=l[i]-'A'+1;
33         max0=max(max0,a[i+1]);
34     }
35     for(long long i=n;i>=1;i--){
36         ans+=query(a[i]-1);
37         add(a[i],1);
38     }
39     cout<<ans;
40     return 0;
41 }

over

原文地址:https://www.cnblogs.com/saionjisekai/p/9753823.html