• POJ 2299 Ultra-QuickSort(树状数组+离散化)


    http://poj.org/problem?id=2299

    题意:
    给出一组数,求逆序对。

    思路:

    这道题可以用树状数组解决,但是在此之前,需要对数据进行一下预处理。

    这道题目的数据可以大到999,999,999,但数组肯定是无法开这么大的,但是每组数据最多只有500000个,那么,怎么办呢,离散化!

    离散化,也就是将数据和1~n做一一映射。

    比如:

    9 1 0 5 4

    离散化之后变成

    5 2 1 4 3

    这样的话,就可以放心的开数组啦!

    至于树状数组的计算过程,我懒得写了,直接摘抄一下大神的http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html

    在离散结果中间结果的基础上,那么其计算逆序数的过程是这么一个过程。
    
    1,输入5,   调用upDate(5, 1),把第5位设置为1
    
    1 2 3 4 5
    
    0 0 0 0 1
    
    计算1-5上比5小的数字存在么? 这里用到了树状数组的getSum(5) = 1操作,
    
    现在用输入的下标1 - getSum(5) = 0 就可以得到对于5的逆序数为0。
    
    2. 输入2, 调用upDate(2, 1),把第2位设置为1
    
    1 2 3 4 5
    
    0 1 0 0 1
    
    计算1-2上比2小的数字存在么? 这里用到了树状数组的getSum(2) = 1操作,
    
    现在用输入的下标2 - getSum(2) = 1 就可以得到对于2的逆序数为1。
    
    3. 输入1, 调用upDate(1, 1),把第1位设置为1
    
    1 2 3 4 5
    
    1 1 0 0 1
    
    计算1-1上比1小的数字存在么? 这里用到了树状数组的getSum(1) = 1操作,
    
    现在用输入的下标 3 - getSum(1) = 2 就可以得到对于1的逆序数为2。
    
    4. 输入4, 调用upDate(4, 1),把第5位设置为1
    
    1 2 3 4 5
    
    1 1 0 1 1
    
    计算1-4上比4小的数字存在么? 这里用到了树状数组的getSum(4) = 3操作,
    
    现在用输入的下标4 - getSum(4) = 1 就可以得到对于4的逆序数为1。
    
    5. 输入3, 调用upDate(3, 1),把第3位设置为1
    
    1 2 3 4 5
    
    1 1 1 1 1
    
    计算1-3上比3小的数字存在么? 这里用到了树状数组的getSum(3) = 3操作,
    
    现在用输入的下标5 - getSum(3) = 2 就可以得到对于3的逆序数为2。
    
    6. 0+1+2+1+2 = 6 这就是最后的逆序数
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 #include<stack>
    10 using namespace std;
    11 
    12 const int maxn=500000+5;
    13 
    14 int n;
    15 
    16 struct node
    17 {
    18     int val;
    19     int pos;
    20 }a[maxn];
    21 
    22 int b[maxn];
    23 int c[maxn];
    24 
    25 bool cmp(node a,node b)
    26 {
    27     return a.val<b.val;
    28 }
    29 
    30 int lowbit(int x)
    31 {
    32     return x&-x;
    33 }
    34 
    35 int sum(int x)
    36 {
    37     int ret=0;
    38     while(x>0)
    39     {
    40         ret+=c[x];
    41         x-=lowbit(x);
    42     }
    43     return ret;
    44 }
    45 
    46 void add(int x,int d)
    47 {
    48     while(x<=n)
    49     {
    50         c[x]+=d;
    51         x+=lowbit(x);
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     //freopen("D:\input.txt","r",stdin);
    58     while(~scanf("%d",&n) && n)
    59     {
    60         for(int i=1;i<=n;i++)
    61         {
    62             scanf("%d",&a[i].val);
    63             a[i].pos=i;
    64         }
    65         sort(a+1,a+1+n,cmp);
    66         for(int i=1;i<=n;i++)
    67             b[a[i].pos]=i;
    68         memset(c,0,sizeof(c));
    69         long long ans=0;
    70         for(int i=1;i<=n;i++)
    71         {
    72             add(b[i],1);
    73             ans+=i-sum(b[i]);
    74         }
    75         printf("%lld
    ",ans);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    Ios插件开发
    React-Native学习指南
    APP测试基本流程
    iOS开发-由浅至深学习block
    你真的会用UITableView嘛
    iOS系统右滑返回全局控制方案
    优化UITableViewCell高度计算的那些事
    UITableViewCell高度自适应探索--AutoLayout结合Frame
    UITableView优化技巧
    页面间跳转的性能优化(一)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6821364.html
Copyright © 2020-2023  润新知