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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    SQLSERVER查询数据库文件大小
    SQLSERVER 检查内容
    20万DBA都在关注的12个问题 [转载]
    oswbb工具分析主机性能
    Suspending MMON slave action kewrmapsa_ for 82800 seconds
    一次direct path read 故障处理
    Auto Optimizer Stats Collection in 12c
    ORACLE 动态注册和静态注册的区别(转)
    记一次cursor pin s wait on X的处理
    树莓派3b的raspberrypi系统安装pip
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13412842.html
Copyright © 2011-2022 走看看