zoukankan      html  css  js  c++  java
  • [2018-2019, ICPC, Asia Yokohama Regional Contest 2018] Problem G-What Goes Up Must Come Down(树状数组)

    [2018-2019, ICPC, Asia Yokohama Regional Contest 2018] Problem G-What Goes Up Must Come Down

    题面:

    Several cards with numbers printed on them are lined up on the table.
    We’d like to change their order so that first some are in non-decreasing order of the numbers on
    them, and the rest are in non-increasing order. For example, (1, 2, 3, 2, 1), (1, 1, 3, 4, 5, 9, 2),
    and (5, 3, 1) are acceptable orders, but (8, 7, 9) and (5, 3, 5, 3) are not.
    To put it formally, with n the number of cards and b i the number printed on the card at
    the i-th position (1 ≤ i ≤ n) after reordering, there should exist k ∈ {1,...,n} such that
    (b i ≤ b i+1 ∀i ∈ {1,...,k − 1}) and (b i ≥ b i+1 ∀i ∈ {k,...,n − 1}) hold.
    For reordering, the only operation allowed at a time is to swap the positions of an adjacent card
    pair. We want to know the minimum number of swaps required to complete the reorder.

    思路:

    对于每个数,都有两种选择:

    1、参与non-decreasing 部分,成本为:该数之前的比该数大的数的个数。

    2、参与non-increasing 部分,成本为:该数之后的比该数大的数的个数。

    我们只需要对每一个数的2种选择的成本取一个最小值加起来即可。

    然后问题就转化为了对于一个数(a_i),求该数之前的比该数大的数的个数和该数之后的比该数大的数的个数。

    方法为:把每一个数的下标都扔进数字对应的桶中,

    用树状数组动态处理前缀和,对于([1,n])这n个下标,初始bit里都加1。

    然后从小到大枚举数字,建设当前枚举到(mathit x),将x的桶中下标值bit里都减去1,同时用一个变量(residue)代表桶中还剩余多少个数没被删除,设(mathit x) 的下标为(mathit j) 那么:

    选择1的成本为:(ask(j))([1,j])的前缀和,因为([1,j])中比(mathit x) 小的数都被之前操作删除过了。

    选择2的成本为:(residue-ask(j))([j+1,n])的前缀和。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <bitset>
    #include <unordered_map>
    // #include <bits/stdc++.h>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x)  if(DEBUG_Switch) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    void pvarr_int(int *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%d%c", arr[i], i == n ? '
    ' : ' ');}}
    void pvarr_LL(ll *arr, int n, int strat = 1) {if (strat == 0) {n--;} repd(i, strat, n) {printf("%lld%c", arr[i], i == n ? '
    ' : ' ');}}
    const int maxn = 1000010;
    const ll inf = 1e18;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    #define DEBUG_Switch 0
    
    ll tree[maxn];
    int lowbit(int x)
    {
        return (-x)& x;
    }
    void add(int pos, int val)
    {
        while (pos < maxn)
        {
            tree[pos] += val;
            pos += lowbit(pos);
        }
    }
    int ask(int pos)
    {
        int res = 0;
        while (pos > 0)
        {
            res += tree[pos];
            pos -= lowbit(pos);
        }
        return res;
    }
    int n;
    int a[maxn];
    std::vector<int> v[maxn];
    int main()
    {
    #if DEBUG_Switch
        freopen("C:\code\input.txt", "r", stdin);
    #endif
        //freopen("C:\code\output.txt","r",stdin);
        n = readint();
        repd(i, 1, n)
        {
            a[i] = readint();
            add(i, 1);
            v[a[i]].push_back(i);
        }
        int residue = n;
        ll ans = 0;
        repd(i, 1, 100000)
        {
            if (sz(v[i]) == 0)
                continue;
            for (auto &x : v[i])
            {
                add(x, -1);
                residue--;
            }
            for (auto &x : v[i])
            {
                ans += min(residue - ask(x), ask(x));
            }
        }
        printf("%lld
    ", ans );
        return 0;
    }
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    springboot设置banner
    pytorch(分布式)数据并行个人实践总结——DataParallel/DistributedDataParallel
    jupyter之配置自己喜欢的python环境
    ImportError: DLL load failed: 找不到指定的模块;ImportError: numpy.core.multiarray failed to import 报错解决
    multitask learning 相关论文资源
    python如何删除二维或者三维数组/列表中某维的空元素
    finished with exit code -1073740791 (0xC0000409)解决方案
    Keras学习系列——神经网络层组件
    腾讯云搭建个人博客wordpress
    多任务学习相关资料整理
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13412842.html
Copyright © 2011-2022 走看看