poj2299 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
题意:有一种排序,规则为如果相邻两数左比右大就交换他们,求最小交换次数?
题解:显然最小次数为逆序对数,至于逆序对,可以归并排序求,也可以树状数组/线段树求,自然是选择简单的喽!
代码如下:
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson root<<1
#define rson root<<1|1
#define hi puts("hi!");
using namespace std;

struct node
{
    int kd,val;
}a[500005];

int n,m,cnt[500050];
long long tr[2000050];

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

void push_up(int root)
{
    tr[root]=tr[lson]+tr[rson];
}

void build(int root,int l,int r)
{
    if(l==r)
    {
        tr[root]=0;
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    push_up(root);
}

void add(int root,int l,int r,int x,int p)
{
    
    if(l==r)
    {
        tr[root]=1;
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid)
    {
        add(lson,l,mid,x,p);
    }
    if(p>mid)
    {
        add(rson,mid+1,r,x,p);
    }
    push_up(root);
}

long long query(int root,int l,int r,int x,int y)
{
    long long ans=0;
    if(x<=l&&y>=r)
    {
        return tr[root];
    }
    int mid=(l+r)>>1;
    if(x<=mid)
    {
        ans+=query(lson,l,mid,x,y);
    }
    if(y>mid)
    {
        ans+=query(rson,mid+1,r,x,y);
    }
    return ans;
}

int main()
{
    while(scanf("%d",&n)==1&&n)
    {
        long long ans1=0;
        memset(tr,0,sizeof(tr));
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].val);
            a[i].kd=i;
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            cnt[a[i].kd]=i;
        }
        for(int i=n;i>=1;i--)
        {
            ans1+=query(1,1,n,1,cnt[i]);
            add(1,1,n,1,cnt[i]);
        }
        printf("%lld
",ans1);
    }
}










 
原文地址:https://www.cnblogs.com/stxy-ferryman/p/8463116.html