zoukankan      html  css  js  c++  java
  • 牛客多校第五场-D-inv

    链接:https://www.nowcoder.com/acm/contest/143/D
    来源:牛客网

    题目描述

    Kanade has an even number n and a permutation b of all of the even numbers in [1,n]
    Let a denote an array [1,3,5....n-1] , now you need to find a permutation of [1,n] satisfy both a and b are subsequence of it and minimize the number of inverse pair of it.

    输入描述:

    The first line has a positive even integer n

    The second line has n/2 positive even integers b[i]

    输出描述:

    Output the number of inverse pair of the permutation you find.
    示例1

    输入

    复制
    6
    2 6 4

    输出

    复制
    2

    说明

    [1,2,3,5,6,4]

    备注:

    1≤ n≤ 2e5

    题意就是给你1-n之间所有偶数的一个排列,让你把奇数插入进去,使得生成的数列的逆序数最少。
    
    为了使得逆序数最少,所有的奇数肯定是有序插入的,因此插入的位置肯定也是递增的。
    对每个奇数找到插入之后产生逆序数最少的位置插入即可。 考虑用c[i]表示将当前奇数 2k
    +1 插入第i个位置时,产生的逆序数。 那么对于 2(k+1) +1 来说,c数组的变化其实是非常小的。 对于所有在 2(k+1) 这个数字之前的位置来说,放2(k+1)+1比放2k+1会多一个逆序数,而在它之后的位置会少一个。 因此用线段树维护c数组,每次选择逆序数最少的位置放即可。
    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2e5+50;
    int n,m;
    int c[N],mn[N*4],lazy[N*4],t[N*4],b[N],pos[N];
    ll ans;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x)
    {
        for (int i=x;i<=n;i+=lowbit(i))
        t[i]++;
    }
    int sum(int x)
    {
        int ret=0;
        for (int i=x;i>=1;i-=lowbit(i))
        ret+=t[i];
        return ret;
    }
    void PushUp(int s)
    {
        mn[s]=min(mn[s<<1],mn[s<<1|1]);
    }
    void PushDown(int s,int lenl,int lenr)
    {
        if (lazy[s])
        {
            mn[s<<1]+=lazy[s];
            mn[s<<1|1]+=lazy[s];
            lazy[s<<1]+=lazy[s];
            lazy[s<<1|1]+=lazy[s];
            lazy[s]=0;
        }
    }
    void build(int s,int l,int r)
    {
        if (l==r)
        {
            mn[s]=c[l];
            return ;
        }
        int mid=(l+r)>>1;
        build(s<<1,l,mid);
        build(s<<1|1,mid+1,r);
        PushUp(s);
    }
    void Updata(int s,int l,int r,int L,int R,int val)
    {
        if (L<=l&&r<=R)
        {
            mn[s]+=val;
            lazy[s]+=val;
            return ;
        }
        int mid=(l+r)>>1;
        PushDown(s,mid-l+1,r-mid);
        if (L<=mid) Updata(s<<1,l,mid,L,R,val);
        if (R>mid) Updata(s<<1|1,mid+1,r,L,R,val);
        PushUp(s);
    }
    int main()
    {
        scanf("%d",&n);
        int m=n/2;
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&b[i]);
            pos[b[i]]=i;
            add(b[i]);
            ans+=i-sum(b[i]);
        }
    
        m++;
        for (int i=1;i<=m+1;i++) c[i]=i-1;
        build(1,1,m);
        for (int i=3;i<=n;i+=2)
        {
            Updata(1,1,m,1,pos[i-1],1);
            Updata(1,1,m,pos[i-1]+1,m,-1);
            ans+=mn[1];
        }
    
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    python---常见排序算法
    flask之session
    Python常考面试题
    MySQL一致性非锁定读原理以及MVCC简介
    mysql面试常考知识点
    数据库学习笔记4数据系统的组成
    工作记录之拯救rm -rf /*(无root权限拯救恢复基础功能)
    数据库学习笔记3数据库的系统结构
    数据库学习笔记2数据模型
    数据库学习笔记1
  • 原文地址:https://www.cnblogs.com/tetew/p/9419548.html
Copyright © 2011-2022 走看看