zoukankan      html  css  js  c++  java
  • 【线段树求逆序数】【HDU1394】Minimum Inversion Number

    题目大意:

    随机给你全排列中的一个,但不断的把第一个数丢到最后去,重复N次,形成了N个排列,问你这N个排列中逆序数最小为多少


    做法:

    逆序数裸的是N^2 利用线段树可以降到NlogN


    具体方法是插入一个数,查询之前比他大的数有多少个,即query(A[i]+1,N,1,N,1),利用线段树保存区间和即可;


    至于不断把一个数丢到最后,可以用O(1)的时间来处理 即  temp=temp-A[i]+(N-A[i]-1);  这个地方很容易思考的 不解释了




    完整代码如下:

    /*
    1.WA 忘记初始化线段树
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define maxn 5555
    int tree[maxn*4];
    int N;
    int A[maxn];
    void input()
    {
        for(int i=1;i<=N;i++)
        scanf("%d",&A[i]);
    }
    int PushUp(int rt)
    {
        tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    }
    int updata(int p,int k,int l,int r,int rt)
    {
        int m;
        if(l==r) {tree[rt]+=k;return 0;}
        m=(l+r)>>1;
        if(p<=m) updata(p,k,lson);
        else updata(p,k,rson);
        PushUp(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int temp=0,m;
        if(L<=l&&r<=R) return tree[rt];
        m=(l+r)>>1;
        if(L<=m) temp=temp+query(L,R,lson);
        if(R>m) temp=temp+query(L,R,rson);
        return temp;
    }
    void solve()
    {
        int ans=0x3f3f3f3f;
        int temp=0;
        for(int i=1;i<=N;i++)
        {
            temp=temp+query(A[i]+1,N,1,N,1);
            updata(A[i],1,1,N,1);
        }
        ans=temp;
        for(int i=1;i<=N-1;i++)
        {
            temp=temp-A[i]+(N-A[i]-1);
            if(temp<ans) ans=temp;
        }
        printf("%d
    ",ans);
    }
    int main()
    {
    	while(cin>>N)
        {
            memset(tree,0,sizeof(tree));
            input();
            solve();
        }
    }
    


  • 相关阅读:
    114.完全背包【恰好装满完全背包
    整数划分类型题目
    三目运算符
    关于 xk 的位数。
    多重背包二进制原理拆分问题
    2016.4.2 讲课笔记(动态规划)
    二叉树(2)二叉树创建的3种方法,二叉树的递归遍历,二叉树的销毁
    二叉树(1)已知某2种排序方式,创建这个二叉树并按第3种方式排序
    C++知识点总结(二)
    5款优秀的开源克隆软件
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480382.html
Copyright © 2011-2022 走看看