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 bi the number printed on the card at the i-th position (1 ≤ i ≤ n) after reordering, there should exist k ∈ {1, . . . , n} such that (bi ≤ bi+1 ∀i ∈ {1, . . . , k − 1}) and (bi ≥ bi+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.

Input

The input consists of a single test case of the following format. n a1 . . . an An integer n in the first line is the number of cards (1 ≤ n ≤ 100 000). Integers a1 through an in the second line are the numbers printed on the cards, in the order of their original positions (1 ≤ ai ≤ 100 000).

Output

Output in a line the minimum number of swaps required to reorder the cards as specified.

Sample Input 1

1 7 3 1 4 1 5 9 2

Sample Output 

3

题意:

相邻的数字交换,求交换次数,使原数组变成前半部分为非降序列,后半部分为非升序列。

思路:

较小的必定在较大的外层,所以可以先把较小的数字移到外层。

移动到最外层的步数要O1算出,计算方法就是用树状数组记录中间已经被移走的数字个数,移到最边上的时候忽视被移走的数字就行了。

对于某一个确定的数字x,要算出4个值,最左边的x移到最左边的步数,移到最右边的步数,最右边的x移到最右边的步数,移到最左边的步数。这四个值的最小值取到哪里(左边的x或者右边的x),就把这个数移走。并更新树状数组。

代码(队友写的)

#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = ;
const int maxn = 1e5 + ;
const int mod = 1e9 + ;
int bit[maxn];
int n;
int a[maxn];
int lowbit(int i) {
return i & -i;
}
void add(int i, int x) {
while (i <= ) {
bit[i] += x;
i += lowbit(i);
}
}
int sum(int i) {
int num = ;
while (i) {
num += bit[i];
i -= lowbit(i);
}
return num;
} vector<int>v[maxn];
int main() {
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
for (int i = ; i <= n; i++) {
v[a[i]].push_back(i);
}
ll ans = ;
for (int k = ; k <= ; k++) {
int i = , j = v[k].size() - ;
while (i <= j) {
int t1 = v[k][i] - sum(v[k][i]) - ;
int t2 = n - v[k][i] - (sum() - sum(v[k][i]));
int t3 = v[k][j] - sum(v[k][j]) - ;
int t4 = n - v[k][j] - (sum() - sum(v[k][j]));
int MIN1 = min(t1, t2);
int MIN2 = min(t3, t4);
if (MIN1 < MIN2) {
add(v[k][i], );
i++;
} else {
add(v[k][j], );
j--;
}
// fuck();
// int MIN=min(MIN);
ans += min(MIN1, MIN2);
}
}
printf("%lld\n", ans);
return ;
}

Gym102082 G-What Goes Up Must Come Down(树状数组)的更多相关文章

  1. 2020牛客寒假算法基础集训营3 G.牛牛的Link Power II (树状数组维护前缀和)

    https://ac.nowcoder.com/acm/contest/3004/G 发现每个“1”对于它本身位置产生的影响贡献为0,对前面的“1”有产生贡献,对后面的"1"也产生 ...

  2. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)

    题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, …, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...

  3. codeforces 589G G. Hiring(树状数组+二分)

    题目链接: G. Hiring time limit per test 4 seconds memory limit per test 512 megabytes input standard inp ...

  4. SCUT - G - 魔法项链 - 树状数组

    https://scut.online/contest/30/G 很久以前做的一个东西,当时是对R排序之后树状数组暴力统计当前区间的前缀和.每有一个元素出现在R的范围内,就解除他的同样元素的影响,在他 ...

  5. G. 24 观察 + 树状数组

    http://codeforces.com/gym/101257/problem/G 首先要看到题目,题目是本来严格大于score[i] > score[j].然后score[i] < s ...

  6. 第十二届湖南省赛G - Parenthesis (树状数组维护)

    Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions. The i-th questio ...

  7. 洛谷 P4375 [USACO18OPEN]Out of Sorts G(树状数组求冒泡排序循环次数加强版)

    传送门:Problem 4375 参考资料: [1]:https://www.cnblogs.com/Miracevin/p/9662350.html [2]:https://blog.csdn.ne ...

  8. 洛谷 P3660 [USACO17FEB]Why Did the Cow Cross the Road III G(树状数组)

    题目背景 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 题目描述 The layout of Farmer ...

  9. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】

    任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...

随机推荐

  1. 老男孩python学习自修第十四天【序列化和json】

    序列化是使用二进制的方式加密列表,字典或集合,反序列化是解密的过程:序列化开启了两个独立进程进行数据交互的通路 使用pickle进行序列化和反序列化 例如: pickle_test.py #!/usr ...

  2. 如何在mac下安装php

    步骤如下: 1.下载php源码并解压 2.进入php源码并configure 3.安装openssl 4.sudo make及make test 5.sudo make install 具体命令如下: ...

  3. fdisk磁盘分区与挂载

    参考博客:https://blog.csdn.net/capecape/article/details/78499351?locationNum=6&fps=1 1.查看磁盘分区情况.root ...

  4. github---无命令可视化界面操作

    最近工作需要,研究了一下git,这个东西挺实用,给我的感觉并不是那么简单使用,我认为还可以再深入的研究一下,挺好玩的~ 说一下我的学习路线: 1.先看的廖老师的博客:https://www.liaox ...

  5. Java 获取客户端ip返回127.0.0.1问题

    Java开发中使用 request.getRemoteAddr 获取客户端 ip ,返回结果始终为127.0.0.1.原因是服务器使用了nginx反向代理. 解决办法:在nginx配置文件nginx. ...

  6. [SimplePlayer] 实现一个简单的播放器

    简单的播放器需要实现一个最基本的功能:播放视频文件. 实现这个功能需要包含以下几个步骤: 从视频文件中提取视频图像 在屏幕上显示视频图像 视频帧的同步,也就是保证视频图像在合适的时间在屏幕上显示 从视 ...

  7. Redis 5种数据结构

    转载:https://baijiahao.baidu.com/s?id=1593806211408070879&wfr=spider&for=pc Redis数据类型 Redis支持五 ...

  8. this view is not constrainted......

    this view is not constrainted 解决方案: <EditText android:id="@+id/editText" android:layout ...

  9. DRF 版本和认证

    Django Rest Framework 版本控制组件 DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们 ...

  10. 【BZOJ2431】【HAOI2009】逆序对数列 DP

    题目大意 问你有多少个由\(n\)个数组成的,逆序对个数为\(k\)的排列. \(n,k\leq 1000\) 题解 我们考虑从小到大插入这\(n\)个数. 设当前插入了\(i\)个数,插入下一个数可 ...