zoukankan      html  css  js  c++  java
  • hdu-1394(线段树&逆序数的性质和求法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394

    题目大意:

    给出一个序列,一对逆序数就是满足i<j&&a[i]>a[j]条件的一对数字。

    每次将a数组的最后一个数放到数组的第一位上,原数组向后移动一位,得到一个新的序列,

    求这些序列中最小的逆序数。(每个数都在0-n-1范围内)

    求解思路:

    (1)逆序数的性质:一个序列第i次循环的逆序数Pi=P(i-1)+(n-1-a[i])-a[i]。

    (2)可以通过暴力求解,每次找最小值就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 5500;
    const int INF = 99999999;
    int a[maxn];
    int main(void)
    {
        int mi,cnt,i,j,num,n;
        while(~scanf("%d",&n))
        {
            memset(a,0,sizeof(a));
            for(i=0;i<n;i++) scanf("%d",&a[i]);
            mi=INF;cnt=0;
            for(i=0;i<n;i++)
                for(j=i+1;j<n;j++)
                if(a[i]>a[j]) cnt++;
            if(mi>cnt) mi=cnt;
            for(i=0;i<n;i++)
            {
                cnt=cnt+(n-1-a[i])-a[i];
                if(mi>cnt) mi=cnt;
            }
            printf("%d
    ",mi);
        }
        return 0;
    }
    View Code

    (3)线段树做法:

    先初始化线段树都为0,然后输入每个数,每个数字+1,即改为1-n区间,判断b[i]+1到n区间内有无数字,有的话逆序数就+1

    然后再更新节点b[i]表示这个节点被访问过了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 5500;
    const int INF = 99999999;
    int a[maxn<<2],b[maxn];
    void pushup(int x)
    {
        a[x]=a[x*2]+a[x*2+1];
    }
    void build(int x,int l,int r)
    {
        if(l==r)
        {
            a[x]=0;return ;
        }
        int mid=(l+r)/2;
        build(x*2,l,mid);
        build(x*2+1,mid+1,r);
        pushup(x); 
    }
    void update(int x,int l,int r,int pos)
    {
        if(l==r)
        {
            a[x]++;return ;
        }
        int mid=(l+r)/2;
        if(pos<=mid) update(x*2,l,mid,pos);
        if(pos>mid) update(x*2+1,mid+1,r,pos);
        pushup(x);
    }
    int query(int x,int l,int r,int A,int B)
    {
        if(A<=l&&r<=B) return a[x];
        int mid=(l+r)/2,ans=0;
        if(A<=mid) ans+=query(x*2,l,mid,A,B);
        if(B>mid) ans+=query(x*2+1,mid+1,r,A,B);
        return ans;
    }
    int main(void)
    {
        int n,i,ans,mi;
        while(~scanf("%d",&n))
        {
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            build(1,1,n);
            ans=0;mi=INF;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
                b[i]++;
                ans+=query(1,1,n,b[i]+1,n);
                update(1,1,n,b[i]);
            }
            if(mi>ans) mi=ans;
            for(i=1;i<n;i++)
            {
                ans=ans+(n-b[i]+1)-b[i];
                if(mi>ans) mi=ans;
            }
            printf("%d
    ",mi);
        }
        return 0;
    }
    View Code

    (4)归并排序做法

    归并排序时,当a[j]>a[i]时,每次记录tmp+=(mid-i+1),最终求出的tmp就是这个序列的逆序数。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 5500;
    int a[maxn],b[maxn],temp[maxn],tmp;
    void Merge_Sort(int l,int r,int mid)
    {
        int pos=0,i=l,j=mid+1;
        while(i<=mid&&j<=r)
        {
            if(a[i]>a[j]) tmp+=(mid+1-i),temp[pos++]=a[j++];
            else temp[pos++]=a[i++];
        }
        while(i<=mid) temp[pos++]=a[i++];
        while(j<=r) temp[pos++]=a[j++];
        for(i=0;i<pos;i++) a[i+l]=temp[i];
    }
    void Merge(int l,int r)
    {
        if(l==r) return ;
        int mid=(l+r)/2;
        Merge(l,mid);
        Merge(mid+1,r);
        Merge_Sort(l,r,mid);
    }
    int main(void)
    {
        int n,ans,i;
        while(~scanf("%d",&n))
        {
            for(i=0;i<n;i++)
            {
                scanf("%d",&a[i]);b[i]=a[i];
            }
            tmp=0;ans=99999999;
            Merge(0,n-1);
            ans=tmp;
            for(i=0;i<n;i++){
                tmp=tmp+n-1-b[i]*2;
                if(ans>tmp) ans=tmp;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    some tips
    ORA00847: MEMORY_TARGET/MEMORY_MAX_TARGET and LOCK_SGA cannot be set together
    Chapter 01Overview of Oracle 9i Database Perfomrmance Tuning
    Chapter 02Diagnostic and Tuning Tools
    变量与常用符号
    Chapter 18Tuning the Operating System
    标准输入输出
    Trace files
    DBADeveloped Tools
    Chapter 03Database Configuration and IO Issues
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10143609.html
Copyright © 2011-2022 走看看