首页 > 其他 > 详细

What Goes Up Must Come Down

时间:2021-09-01 20:03:06      阅读:12      评论:0      收藏:0      [点我收藏+]

题目描述

给定一个序列, 求出将此序列变换为单调递增单调递减 或者先增后减

样例1

输入
7 
3 1 4 1 5 9 2
输出
3

样例2

输入
9 
10 4 6 3 15 9 1 1 12
输出
8

分析

本题相当于是有一个峰值, 峰值两边的都单调递减
我们可以用树状数组求出对于所有的数字处于峰值左边或者右边所需要的交换次数
对于这两种情况取一个最小值即可

CODE

#include <iostream>
#define lowbit(i) i & -i
#define mset(a) for(int i = 0; i <= px; i ++ ) a[i] = 0

using namespace std;

const int N = 1e5 + 10;

int n, px;
int a[N], tr[N], cnt[N];

void add(int x) {
    for(int i = x; i <= px; i += lowbit(i) ) tr[i] ++;
}

int sum(int x) {
    int ans = 0;
    for(int i = x; i; i -= lowbit(i)) ans += tr[i];
    return ans;
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++ ) {
        cin >> a[i];
        px = max(a[i], px);
    }

    for(int i = 1; i <= n; i ++ ) {
        cnt[i] = sum(px) - sum(a[i]);
        add(a[i]);
    }
    mset(tr);
    for(int i = n; i; i -- ) {
        cnt[i] = min(sum(px) - sum(a[i]), cnt[i]);
        add(a[i]);
    }
    long long ans = 0;
    for(int i = 1; i <= n; i ++ ) ans += cnt[i];
    cout << ans << endl;
    return 0;
}

What Goes Up Must Come Down

原文:https://www.cnblogs.com/c972937/p/15207989.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!