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;
    }
  • 相关阅读:
    编码
    浏览器翻页
    验证码识别
    时间
    phantomjs配置
    产品
    java范型的理解
    使用JDBC连接数据库
    垃圾回收机制
    java的内存区域 && java内存模型
  • 原文地址:https://www.cnblogs.com/Gloid/p/9833852.html
Copyright © 2011-2022 走看看