zoukankan      html  css  js  c++  java
  • hdu 1394

    1A...火车上写的,,。

    学到:
    1、明白特征。分类讨论。能够防止计数反复

    求逆序数的时候,算出以每一个数为逆序数对的第二个数的情况之和即为序列的逆序数,这样能够防止反复

    2、假设没有思路。就先从若干情况入手,自己模拟试试。找规律

    这道题的规律就是,如果全部比x[i]小的数个数为c,那么当把第一个数移到序列最后,产生的新的逆序对个数为sum=sum-c+n-1-c;,降低了c,添加了n-1-c


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define lson(i) l,mid,(i)*2
    #define rson(i) mid+1,r,((i)*2+1)
    #define ll rt*2
    #define rr (rt*2+1)
    const int MAXN = 5000+10;
    struct Node{int l,r,tot;}nodes[MAXN*4];
    
    int x[MAXN],n,d[MAXN],y[MAXN];
    
    void Pushup(int rt)
    {
        nodes[rt].tot = nodes[ll].tot + nodes[rr].tot;
    }
    
    void build(int rt, int l, int r)
    {
        nodes[rt].l=l;
        nodes[rt].r=r;
        nodes[rt].tot=0;
        if(l == r)
        {
            return;
        }
        int mid=(l+r)/2;
        build(ll,l,mid);
        build(rr,mid+1,r);
    }
    
    void Update(int rt, int p, int v)
    {
        if(nodes[rt].l == nodes[rt].r)
        {
            nodes[rt].tot=1;
            return;
    
        }
        int mid=(nodes[rt].l+nodes[rt].r)/2;
        if(p<=mid)
        {
            Update(rt*2,p,v);
        }
        else
        {
            Update(rr,p,v);
        }
        Pushup(rt);
    }
    
    int Query(int rt, int l, int r)
    {
        if(l == nodes[rt].l && r == nodes[rt].r)
        {
            return nodes[rt].tot;
        }
        int mid=(nodes[rt].l+nodes[rt].r)>>1;
        if(r<=mid)return Query(ll,l,r);
        else
        {
            if(l>mid)
            {
                return Query(rr,l,r);
            }
            else
            {
                return Query(ll,l,mid)+Query(rr,mid+1,r);
            }
        }
    }
    
    int main()
    {
        freopen("hdu1394.txt","r",stdin);
        while(~scanf("%d",&n))
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&x[i]);
                x[i]+=1;
            }
            build(1,1,n);
            for(int i=1;i<=n;i++)
            {
                Update(1,x[i],1);
                d[i]=Query(1,1,x[i])-1;
            }
            int sum=0,ans=n;
            for(int i=1;i<=n;i++)
            {
                y[i]=Query(1,1,x[i])-1-d[i];//y[i] x[i]右側比之小的数个数
                sum+=(i-1-d[i]);
            }
            /////////////////////////
           /* for(int i=1;i<=n;i++)
            {
                printf("i=%d d=%d y=%d
    ",i,d[i],y[i]);
            }
            printf("sum=%d
    ",sum);*/
            //////////////
            int c;
            ans=sum;
            for(int i=1;i<=n;i++)
            {
                c=y[i]+d[i];
                sum=sum-c+n-1-c;
                ans=min(ans,sum);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    windows 10下ELK环境快速搭建实践
    Windows 10下搭建以太坊私有链环境
    线程状态转换图
    JAVA中IO技术:BIO、NIO、AIO
    MySQL MDL锁的阻塞问题 & online ddl的插队现象【转发】
    MySQL InnoDB MVCC 能否完全解决幻读?
    Linux 计算 存储 网络 统计命令
    MySQL B+ tree & B tree & Hash
    mmap学习总结
    Linux内存分配小结--malloc、brk、mmap【转】
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5263462.html
Copyright © 2011-2022 走看看