avatar
fireworks99
keep hungry keep foolish

树状数组 解 POJ 2299 Quick-Sort

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.

题目链接 http://poj.org/problem?id=2299

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

思路

要查询出当前数字前面有几个比他大的数字,我们可以反着求,用前面的数字个数 - 比当前数字小的个数。而这个小的个数就是用树状数组的查询,开始时,我们把tree数组初始化为0,每当查询完毕一个数,我们就把tree[这个数]加一,这样我们只需要看看当前数字前面总共有多少个1就行了

原文链接 https://blog.csdn.net/weixin_43918531/article/details/87950037

树状数组 https://www.cnblogs.com/hsd-/p/6139376.html

Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 500005;

struct node
{
    int val, pos, num;///pos :输入时的先后顺序
                      ///num :由小到大的先后顺序
}a[N];
int tree[N];

int n;
long long sum;

bool cmp_val(node a, node b)
{
    return a.val < b.val;
}

bool cmp_pos(node a, node b)
{
    return a.pos < b.pos;
}

int lowbit(int x)///得到x最低位1(后面补零)所代表的数
{
    return ( x & (- x) );
}

void update(int pos)///单点更新(向上)
{
    for(int i = pos; i <= n; i += lowbit(i))
        tree[i]++;
}

int query(int pos)///区间查询(向下)
{
    int tem = 0;
    for(int i = pos; i >= 1; i -= lowbit(i))
        tem += tree[i];
    return tem;
}

int main()
{
//    freopen("in.txt", "r", stdin);

    while(~scanf("%d", &n) && n)
    {
        sum = 0;
        memset(tree, 0, sizeof(tree));
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d", &a[i].val);
            a[i].pos = i;
        }
        sort(a + 1, a + 1 + n, cmp_val);///从小到大排序
        for(int i = 1; i <= n; ++i)
            a[i].num = i;
        sort(a + 1, a + 1 + n, cmp_pos);///按输入顺序排序

        ///这个遍历过程需要其输入时的位置和其大小位置
        for(int i = 1; i <= n; ++i)
        {///i代表输入先后顺序,a[i].num代表大小顺序(由小到大)
            sum += i - 1 - query(a[i].num);
            update(a[i].num);
        }
        cout << sum << '\n';
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy