Problem Description

Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage Sherlock's milking equipment, Sherlock would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes Sherlock a total of X + Y units of time to exchange two cows whose grumpiness levels are X and Y.

Please help Sherlock calculate the minimal time required to reorder the cows.

Input

Line 1: A single integer: N
Lines 2..N + 1: Each line contains a single integer: line i + 1 describes the grumpiness of cow i.

Output

Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.

Sample Input

3

2 3 1

Sample Output

7

Hint

Input Details Three cows are standing in line with respective grumpiness levels 2, 3, and 1. Output Details 2 3 1 : Initial order. 2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4). 1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).

题意:给出一组数从1到N打乱,要求把数组重新有序(从小到大),只能交换相邻的两个数字,代价为相邻两个数字和。求最小代价?

首先每次只能交换相邻的两头牛,并且最后要求升序排列,所以最后整个序列的逆序是0,每次交换只可以消除1个逆序。(令a[i]的逆序是从1到i-1比它大的数的个数。)

现在想问我们用插入排序的方式从左到右一个一个消除逆序的话,最后得到的时间和是最小的吗?是的。证明如下:

对于每个原始的a[i],假设在它前面有x和y比a[i]大,所以a[i]的逆序是2,消除a[i]逆序的代价必须是x+y+2a[i],因为如果x或y不与a[i]交换,那么x或y就永远在a[i]前面,逆序不可能消除。所以要消除任意a[i]的逆序,以上代价都是必须的且是最小的

现在用树状数组来求消除逆序的代价。要建两颗树状数组,其中树组1用来计算当前已经有多少个值比a[i]大已经出现了,即temp1(类似于上面例子的2=temp1),树组2用来计算当前所有比a[i]大的值之和是多少?即temp2(x+y=temp2)。

从左到右依次扫描a[i],首先执行temp1=sum(1,MAXN)-sum(1,a[i]);   temp2=sum(2,MAXN)-sum(2,a[i]);则temp1*a[i]+temp2就是消除a[i]逆序的代价,所以ans+=temp1*a[i]+temp2;

然后接着插入a[i],执行:

add(1,a[i],1); add(2,a[i],a[i]);

最终结果可能超出int,要用long long

AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
const int MAXN=100000+100;
ll c[3][MAXN];int lowbit(int x)
{return x&(-x);
}
ll sum(int i,int x)
{ll res=0;while(x>0){res +=c[i][x];x-=lowbit(x);}return res;
}void add(int i,int x,ll v)
{while(x<MAXN){c[i][x]+=v;x+=lowbit(x);}
}int main()
{int n;while(scanf("%d",&n)==1&&n){memset(c,0,sizeof(c));ll ans=0;for(int i=1; i<=n; i++){int x;scanf("%d",&x);ll temp1=sum(1,MAXN)-sum(1,x);ll temp2=sum(2,MAXN)-sum(2,x);ans += temp1*x+temp2;add(1,x,1);add(2,x,x);}printf("%lld\n",ans);}return 0;
}

HDU 2838 Cow Sorting(双树状数组+求逆序数)相关推荐

  1. 离散化+树状数组求逆序数

    题目:http://poj.org/problem?id=2299 离散化是一种常用的技巧,有时数据范围太大,可以用来放缩到我们能处理的范围 因为其中需排序的数的范围0--- 999999999:显然 ...

  2. poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...

  3. hdu 1394(树状数组求逆序数)

    解题思路:这道题是求循环数组中逆序数最小值,求逆序数这里肯定是用树状数组.只是这里有一点点变化,由于题目中n位数是0-n-1的一个排列,所以num[i]可表示为比num[i]小的数的个数.把第一位的数 ...

  4. 归并排序树状数组求逆序数

    归并排序: #include <iostream> #include <vector> using namespace std; vector<int>input, ...

  5. Japan树状数组求逆序数

    http://poj.org/problem?id=3067 给出一个序列 a1 a2 a3 ···an 问此序列中逆序对的个数? 逆序对:i<j,ai>aj 方法:就是用树状数组搞,从后 ...

  6. Swaps and Inversions hdu多校训练第二场 树状数组求逆序数+离散化

    http://acm.hdu.edu.cn/showproblem.php?pid=6318 交换相邻的元素,有几个逆序对,就交换几次使其变成顺序对 #include<bits/stdc++.h ...

  7. HDU 4911 Inversion 树状数组求逆序数对

    显然每次交换都能降低1 所以求出逆序数对数,然后-=k就好了.. . _(:зゝ∠)_ #include<stdio.h> #include<string.h> #includ ...

  8. 牛客练习赛33 D tokitsukaze and Inverse Number (树状数组求逆序对,结论)

    链接:https://ac.nowcoder.com/acm/contest/308/D 来源:牛客网 tokitsukaze and Inverse Number 时间限制:C/C++ 1秒,其他语 ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分...

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

最新文章

  1. 我的微软最有价值专家(Microsoft MVP)之路
  2. 我该建数仓、大数据平台还是数据中台?看完脑子终于清醒了
  3. OpenLiberty:注入时出错,适用于TomEE和Wildfly
  4. 【POJ - 3048】Max Factor (数论,打表,水题)
  5. Mybatis, 实现一对多
  6. 如何排查Oracle表空间不足问题
  7. 2022华为软件精英挑战赛——梯度方法
  8. /proc文件系统详解
  9. CentOS 7 新建桌面快捷方式,实现一键跳转到指定的文件夹路径
  10. maven报错The JAVA_HOME environment variable is not defined correctly
  11. Golang#Typora-Golang笔记
  12. python 零代码快速开发平台_企业如何选择开源的零代码开发平台
  13. JSONObject、JSONArray
  14. 集成方法:渐进梯度回归树GBRT(迭代决策树)
  15. LSP标识符(LSP ID)
  16. 计算机服务里打印设置在哪,打印机模式打印在哪里,教您打印机模式怎么设置...
  17. MyEclipse安装tfs插件
  18. SQL注入 | 黑客入门篇(如何绕过密码登陆账号)
  19. 计算机一级要学多长时间,计算机一级多少分过 一级成绩查询时间
  20. Android个性导航栏效果

热门文章

  1. RedisSystemException:WRONGTYPE Operation against a key holding the wrong kind of value
  2. xxl-job The access token is wrong.
  3. 华中科技大学成立人工智能学院,两名长江学者坐镇
  4. “人不知而不愠”-当别人不理解我们时,怎样保持好心情?
  5. 快速实施多账套多组织架构
  6. [天方夜谭]上帝夜访点点
  7. 学seo要知道什么代码
  8. seo优化后多久能够看见效果
  9. 运维工程师新人培训材料(zz)
  10. 1036Gangsters