zoukankan      html  css  js  c++  java
  • BZOJ4240 有趣的家庭菜园(贪心+树状数组)

      显然相当于使序列变成单峰。给原序列每个数按位置标号,则要求重排后的序列原标号的逆序对数最少。考虑将数从大到小放进新序列,那么贪心的考虑放在左边还是右边即可,因为更小的数一定会在其两侧,与它自身放在哪无关。对于相同的数,一定可以将其安排至之间无逆序对,特判一下。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 300010
    int n,tree[N];
    long long ans=0;
    struct data{int x,i;
    }a[N];
    bool cmp(const data&a,const data&b)
    {
        return a.x>b.x;
    }
    void add(int k){while (k<=n) tree[k]++,k+=k&-k;}
    int query(int k){int s=0;while (k) s+=tree[k],k-=k&-k;return s;}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4240.in","r",stdin);
        freopen("bzoj4240.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++) a[i].x=read(),a[i].i=i;
        sort(a+1,a+n+1,cmp);
        for (int i=1;i<=n;i++)
        {
            int t=i;while (t<n&&a[t+1].x==a[i].x) t++;
            for (int j=i;j<=t;j++) ans+=min(query(a[j].i),i-1-query(a[j].i));
            for (int j=i;j<=t;j++) add(a[j].i);
            i=t;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    linux---shell数组
    linux---shell传递参数
    Windows mysql免安装版配置。(版本号-5.6.45);
    contos 6.9 和 centos7 配置docker?
    数据库表的演化过程
    docker简单介绍。
    Linux 配置 mycat 和 分库分表配置。
    Linux 配置mysql 免安装版。
    mycat 简单介绍
    kibana 对es的简单操作。
  • 原文地址:https://www.cnblogs.com/Gloid/p/9833852.html
Copyright © 2011-2022 走看看