zoukankan      html  css  js  c++  java
  • hdu 1394Minimum Inversion Number

    本题为是对逆序对的查找,问题可为在某个区间共有多少个数被输入,首先为查找初始的逆序对数,然后求将第一个数加入到最后的逆序对数,设初始的逆序对数总共为SUM这将第一个数加入到最后的的逆序对数为SUM加上比A1大的数减去比A1小的数字。即为当前的逆序对数,如此类推,求的比逆序对数最小的。。。

    View Code
    #include<cstdio>
    #include<cstdlib>
    #include<cstdlib>
    #include<cstring>
    #define MAXN  5010
    int seg_tree[MAXN<<2];
    void build_tree(int l,int r,int id);
    int query_tree(int left,int right,int l,int r,int id);
    void update_tree(int left,int right,int l,int r,int id);
    void push_up_tree(int id);
    int x[MAXN];
    int main()
    {
        int n,i,j,k,sum;
        while(scanf("%d",&n)==1)
        {
            sum=0;
            build_tree(0,n-1,1);
            for(i=0;i<n;i++)
            {
                scanf("%d",x+i);
                
            }
            for(i=n-1;i>=0;i--)
            {
                sum+=query_tree(0,x[i],0,n-1,1);
                update_tree(x[i],x[i],0,n-1,1);
            }
            int ret=sum;
            for(i=0;i<n;i++)
            {
                sum+=n-1-x[i]-x[i];
                if(ret>sum)
                    ret=sum;
            }
            printf("%d\n",ret);
    
        }
    }
    void build_tree(int l,int r,int id)
    {
        if(l==r)
        {seg_tree[id]=0;
        return ;
        }
        int m=(l+r)>>1;
        build_tree(l,m,id<<1);
        build_tree(m+1,r,id<<1|1);
        push_up_tree(id);
    }
    int query_tree(int left,int right,int l,int r,int id)
    {
        if(left<=l&&right>=r)
            return seg_tree[id];
        int m=(l+r)>>1,ret=0;
        if(left<=m)
            ret+=query_tree(left,right,l,m,id<<1);
        if(right>m)
            ret+=query_tree(left,right,m+1,r,id<<1|1);
        return ret;
    }
    void update_tree(int left,int right,int l,int r,int id)
    {
        if(l==r)
        {seg_tree[id]++;
        return ;
        }
        int m=(l+r)>>1;
        if(left<=m)
            update_tree(left,right,l,m,id<<1);
        else update_tree(left,right,m+1,r,id<<1|1);
        push_up_tree(id);
    
    }
    void push_up_tree(int id)
    {
        seg_tree[id]=seg_tree[id<<1]+seg_tree[id<<1|1];
    }
  • 相关阅读:
    那些陌生的C++关键字
    从实现装饰者模式中思考C++指针和引用的选择
    单例模式(Singleton)
    命令模式(Command)
    抽象工厂模式(Abstract Factory)
    《Effective C++》读书摘要
    桥接模式(Bridge)
    适配器模式(Adapter)
    设计模式学习心得
    黑客常用WinAPI函数整理
  • 原文地址:https://www.cnblogs.com/woaiyy/p/2522871.html
Copyright © 2011-2022 走看看