• 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);
        }
    }
    
    
    
    
    
    
    
    
    
    
    
     
  • 相关阅读:
    《大型网站技术架构》-读书笔记一:大型网站架构演化
    网站性能测试指标及网站压力测试
    PHP生成二维码
    数据结构与算法之PHP实现队列、栈
    数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)
    PHP 堆 栈 数据段 代码段 存储的理解
    堆”,"栈","堆栈","队列"以及它们的区别
    c#加密
    Sequence contains no elements : LINQ error
    asp.net core2.0 连接mysql和mssql
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8463116.html
Copyright © 2020-2023  润新知