• ICPC Central Russia Regional Contest (CRRC 19)


    K. Parabolic sorting

    题意:给你一个数组,要你重新排序这个数组使得最终的数组前一部分单调递减,后一部分单调递增。

    每次操作可以改变相邻位置的两个数。问你最小操作数。

    刚开始的错误想法是把直接把数组分为两个部分,前一部分排序的操作数加上后一部分的操作数,取最小值。

    正解是:对于每个数取min(前部分小于它的个数,后部分小于它的个数),加起来即是答案。

    用树状数组写食用更加哦!

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5;
    const int mod=998244353;
    const double ep=1e-8;
    #define PLI pair<ll,int>
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    int n,b[maxn],b1[maxn];
    struct node{
        int l,r,sum;
    }a[maxn<<2];
    void build(int k,int l,int r)
    {
        a[k].l=l;a[k].r=r;
        a[k].sum=0;
        if(l==r)return;
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    void pushup(int k)
    {
        a[k].sum=a[k<<1].sum+a[k<<1|1].sum;
    }
    void update(int k,int x)
    {
        if(a[k].l==x&&a[k].r==x)
        {
            a[k].sum=1;return;
        }
        int mid=(a[k].l+a[k].r)>>1;
        if(x<=mid)update(k<<1,x);
        else update(k<<1|1,x);
        pushup(k);
    }
    int query(int k,int l,int r)
    {
        if(a[k].l>=l&&a[k].r<=r)return a[k].sum;
        int mid=(a[k].l+a[k].r)>>1;
        int sum=0;
        if(l<=mid)sum=query(k<<1,l,r);
        if(r>mid)sum+=query(k<<1|1,l,r);
        return sum;
    }
    ll res,l[maxn],r[maxn];
    void solve()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&b[i]),b1[i]=b[i];
        sort(b1+1,b1+1+n);
        for(int i=1;i<=n;i++)b[i]=lower_bound(b1+1,b1+1+n,b[i])-b1;
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            int k=query(1,1,b[i]);
            l[i]=k;
            update(1,b[i]);
        }
        build(1,1,n);
        for(int i=n;i>=1;i--)
        {
            int k=query(1,1,b[i]);
            r[i]=k;
            update(1,b[i]);
        }
        res=0;
        for(int i=1;i<=n;i++)
        {
            res=res+min(l[i],r[i]);
        }
        printf("%lld
    ",res);
    }
    
    int main()
    {
        int T=1;
    //    scanf("%d",&T);
        while(T--)solve();    
    }
    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    strncat_s
    资源编译器 (.rc) 文件
    C++ Namespace 详解
    Structure Definitions
    SetParent
    C++笔记(1)explicit构造函数
    .def
    tellg()和tellp()
    Data Groups
    Messages
  • 原文地址:https://www.cnblogs.com/HHHEN/p/14116234.html
Copyright © 2020-2023  润新知