Ultra-QuickSort POJ - 2299 线段树+离散化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SEVENY_/article/details/89743314

Ultra-QuickSort

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

AC代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int  maxn = 500777;
struct Tree{
    int l, r;
    ll sum;
}tree[maxn << 2];
struct node{
    ll val, pos;
}pos[maxn];
ll res = 0;
int n;
int x[maxn];
void build(int k, int l, int r)
{
    tree[k].l = l;
    tree[k].r = r;
    if(tree[k].l == tree[k].r)
    {
        tree[k].sum = 0;
        return ;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    build(2 * k, l, m);
    build(2 * k + 1, m + 1, r);
    tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
int cmp(struct node a, struct node b)
{
    return a.val < b.val;
}
void change_point(int k, int pos)
{
    if(tree[k].l == pos && tree[k].r == pos)
    {
        tree[k].sum = 1;
        return ;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    if(pos <= m) change_point(2 * k, pos);
    else change_point(2 * k + 1, pos);
    tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
ll query(int k, int l, int r)
{
    if(l > r)return 0;
    if(tree[k].l == l && tree[k].r == r)
    {
        return tree[k].sum;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    if(l > m)
    {
        return query(2 * k + 1, l, r);
    }
    else if(r <= m)
    {
        return  query(2 * k, l, r);
    }
    else
    {
        return query(2 * k, l, m) + query(2 * k + 1, m + 1, r);
    }

}
int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        build(1,1,n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &pos[i].val);
            pos[i].pos = i;
        }
        sort(pos + 1, pos + n + 1, cmp);
        for(int i = 1; i <= n; i++)
        {
            x[pos[i].pos] = i;
        }
        res = 0;
        for(int i = 1; i <= n; i++)
        {
            res = res + x[i] - 1 - query(1,1,x[i] - 1);
            change_point(1,x[i]);
        }
        cout<<res<<endl;
    }
}

使用Map离散化,超时代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int  maxn = 500777;
struct Tree{
    int l, r;
    ll sum;
}tree[maxn << 2];
struct node{
    ll val, pos;
}pos[maxn];
map<ll,ll> mp;
ll res = 0;
int n;
ll x;
int a[maxn], b[maxn];
void build(int k, int l, int r)
{
    tree[k].l = l;
    tree[k].r = r;
    if(tree[k].l == tree[k].r)
    {
        tree[k].sum = 0;
        return ;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    build(2 * k, l, m);
    build(2 * k + 1, m + 1, r);
    tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
int cmp(struct node a, struct node b)
{
    return a.val < b.val;
}
void change_point(int k, int pos)
{
    if(tree[k].l == pos && tree[k].r == pos)
    {
        tree[k].sum = 1;
        return ;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    if(pos <= m) change_point(2 * k, pos);
    else change_point(2 * k + 1, pos);
    tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
ll query(int k, int l, int r)
{
    if(l > r)return 0;
    if(tree[k].l == l && tree[k].r == r)
    {
        return tree[k].sum;
    }
    int m = (tree[k].l + tree[k].r) / 2;
    if(l > m)
    {
        return query(2 * k + 1, l, r);
    }
    else if(r <= m)
    {
        return  query(2 * k, l, r);
    }
    else
    {
        return query(2 * k, l, m) + query(2 * k + 1, m + 1, r);
    }

}
int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        build(1,1,n);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld", &x);
            a[i] = x;
            b[i] = x;
        }
        sort(b + 1,b + 1 + n);
        for(ll i = 1; i <= n; i++)
        {
            mp[b[i]] = i;
        }

        res = 0;
        for(int i = 1; i <= n; i++)
        {
            res = res + mp[a[i]] - 1 - query(1,1,mp[a[i]] - 1);
            change_point(1,mp[a[i]]);
        }
        cout<<res<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/SEVENY_/article/details/89743314