zoukankan      html  css  js  c++  java
  • poj 2299 Ultra-QuickSort(BIT求逆序数)

    Description

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output 
    0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0
    解题思路:题意很简单,树状数组or归并排序求逆序数,这里只讲树状数组的实现!因为a[i]的值高达10^9,树状数组的大小肯定开不了这么大,而n最大为5e5(可作为数组大小,不过大小还要再开大一点,避免越界),因此需要将原来每个元素离散化,即重新编个号(1~n)。
    做法:用一个结构体记录原来每个元素val出现的次序id,然后将结构体按val的大小升序排序,接下来遍历排序后的结构体数组,将原来的元素离散化成1~n,即将id对应原来的数字改成第i大(i∈[1,n]),最后就可以直接用树状数组进行更新和统计逆序数了。
    拿题目中9 1 0 5 4这个样例来加强对数据离散化的理解:
    输入的元素值 9 1 0 5 4 -->排序后 0 1 4 5 9
    对应的次序id 1 2 3 4 5 3 2 5 4 1
    此时将排序后每个id对应的元素离散化成第i小即 1 2 3 4 5,显然0是第1小,且是第3次出现,1是第2小,且是第2次出现...
    这样我们就已经成功地把原来的数据离散化,接下来遍历一下次序id:tar[1]=5(原来为9,9是第一个输入的,这里就变成了5,空间上压缩了不少),先在树状数组中标记为1,并且5前面有4个空为0,于是5(9)这个元素构成了4个逆序对,累加逆序数4并继续按此操作下去即可找出所有的逆序数。
    AC代码:
     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn=500005;
     6 typedef long long LL;
     7 int n,val,aa[maxn],tar[maxn];
     8 struct node{int val,id;}nod[maxn];
     9 bool cmp(node a,node b){return a.val<b.val;}
    10 int lowbit(int x){
    11     return x & -x;
    12 }
    13 void update(int x,int val){
    14     while(x<=n){
    15         aa[x]+=val;
    16         x+=lowbit(x);
    17     }
    18 }
    19 int getsum(int x){
    20     int ret=0;
    21     while(x>0){
    22         ret+=aa[x];
    23         x-=lowbit(x);
    24     }
    25     return ret;
    26 }
    27 int main(){
    28     while(cin>>n&&n){
    29         LL ans=0;
    30         memset(aa,0,sizeof(aa));//注意清空
    31         for(int i=1;i<=n;++i){
    32             cin>>nod[i].val;
    33             nod[i].id=i;//记录元素val出现的次序id
    34         }
    35         sort(nod+1,nod+n+1,cmp);//然后数组元素val按升序排序
    36         for(int i=1;i<=n;++i)tar[nod[i].id]=i;//离散化数据:tar[nod[i].id]表示原来第nod[i].id次出现的值换成现在1~n中的编号i
    37         for(int i=1;i<=n;++i){
    38             update(tar[i],1);//tar[i]表示为输入值的次序:第i次出现的值(已离散化),先将该值在树状数组中标记为1,表示该数字已出现
    39             ans+=tar[i]-getsum(tar[i]);//求出tar[i]前面还没出现数字的个数即为与当前tar[i]构成逆序对的个数,然后累加即可
    40         }
    41         cout<<ans<<endl;
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    Python-http请求
    MacOs Big Sur 11.0.1 安装python报错
    linux 根据时间删除某个目录下的文件
    记一次文件上传遇到的坑(文件名|文件格式乱码)
    json_schema参数校验
    K8s
    python实时视频流播放
    pycharm永久激活
    客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法
    webstorm修改文件,webpack-dev-server及roadhog不会自动编译刷新
  • 原文地址:https://www.cnblogs.com/acgoto/p/9476544.html
Copyright © 2011-2022 走看看