• hdu 1394 逆序数(线段树)


    http://acm.hust.edu.cn/vjudge/problem/15764

    http://blog.csdn.net/libin56842/article/details/8531117

    逆序数的概念:

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。
    也是就说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。
     
    而一个排列的逆序树,可以通过这个方法求得:
    在输入排列每个数时,找之前比它大的数字有多少个,然后插入线段树,最后加起来的结果就是总的逆序数
     
    对于将最后一个数插到最前面,可以通过循环计算求得
     
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <vector>
    #include <iterator>
    #include <set>
    #include <map>
    #include <sstream>
    using namespace std;
    
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pf printf
    #define sf scanf
    #define spf sprintf
    #define pb push_back
    #define debug printf("!
    ")
    #define MAXN 5000 + 5
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #define LL long long
    #define ALL(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    #define pqueue priority_queue
    #define INF 0x3f3f3f3f
    
    struct node
    {
        int l,r,c;
    }T[MAXN*3];
    
    void PushUp(int rt)
    {
        T[rt].c = T[rt<<1].c + T[(rt<<1)+1].c;
    }
    
    void build(int l,int r,int x)
    {
        T[x].l = l;
        T[x].r = r;
        T[x].c = 0;
        if (l == r) return;
        int mid = (l+r)>>1;
        build(l,mid,x<<1);
        build(mid+1,r,(x<<1) + 1);
    }
    
    void update(int l,int x)
    {
        if(T[x].l == T[x].r && T[x].l == l)
        {
            T[x].c++;
            return;
        }
        int mid = (T[x].l + T[x].r)>>1;
        if (l > mid)
        {
            update(l,(x<<1) + 1);
        }
        else
        {
            update(l,x<<1);
        }
        PushUp(x);
    }
    
    int n,m,ans;
    
    void query(int l,int r,int x)
    {
        if(T[x].l == l && T[x].r == r)
        {
            ans += T[x].c;
            return;
        }
        int mid = (T[x].l + T[x].r)>>1;
        if (l > mid)
        {
            query(l,r,(x<<1)+1);
        }
        else if(r<=mid)
        {
            query(l,r,(x<<1));
        }
        else
        {
            query(l,mid,(x<<1));
            query(mid+1,r,(x<<1)+1);
        }
    }
    
    int a[MAXN];
    
    
    int main()
    {
        int t,i,kase=1;
        while(sf("%d",&n)==1)
        {
            build(1,n,1);
            int sum = 0;
            for(i=0;i<n;i++)
            {
                sf("%d",&a[i]);
                a[i]++;
                ans = 0;
                if(a[i]!=n) query(a[i]+1,n,1);
                sum+=ans;
                update(a[i],1);
            }
            int result = sum;
            for(i=n-1;i>=0;i--)
            {
                sum = sum - (n - a[i]) + a[i] -1;
                result = min(result,sum);
            }
            pf("%d
    ",result);
        }
        return 0;
    }
  • 相关阅读:
    【转】千万别理程序员
    qemu-ifup and qemu-ifdown
    Fedora-23 installation in VM image
    Set up bridge to connect to internet
    fedora25 上设置br0
    助教工作总结
    树1
    线性结构
    链表基本操作
    自定义函数
  • 原文地址:https://www.cnblogs.com/qlky/p/5693747.html
Copyright © 2020-2023  润新知