题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6318

Problem Description
Long long ago, there was an integer sequence a.
Tonyfang think this sequence is messy, so he will count the number of inversions in this sequence. Because he is angry, you will have to pay x yuan for every inversion in the sequence.
You don't want to pay too much, so you can try to play some tricks before he sees this sequence. You can pay y yuan to swap any two adjacent elements.
What is the minimum amount of money you need to spend?
The definition of inversion in this problem is pair (i,j) which 1≤i<j≤n and ai>aj.
 
Input
There are multiple test cases, please read till the end of input file.
For each test, in the first line, three integers, n,x,y, n represents the length of the sequence.
In the second line, n integers separated by spaces, representing the orginal sequence a.
1≤n,x,y≤100000, numbers in the sequence are in [−1e9,1e9]. There're 10 test cases.
 
Output
For every test case, a single integer representing minimum money to pay.
 
Sample Input
3 233 666
1 2 3
3 1 666
3 2 1
 
Sample Output
0
3

题意:

给出n个元素的序列,现在你有机会,花费y元交换一次任意相邻两个元素,交换完毕后,若存在逆序对,每一个逆序对要花费x元,求最少的花费。

题解:

考虑冒泡排序:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。做完一遍,最后的元素是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个(因为确定是最大的)。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

显然,我们每交换一次两个相邻元素,就必然能使逆序数减1,而排序完毕后逆序数等于0,所以冒泡排序交换相邻元素次数等于逆序数。

而且同样易知,我们不可能用更少的交换次数使得逆序数等于0。

所以我们就得到了如下结论:

  逆序数 = 在只能交换相邻元素条件下,使得序列有序的最少交换次数

而本题中,交换一次花费x,一个逆序对花费y,也就是说,要么全部交换直到没有逆序对,要么一次也不交换。

所以我们只要求出逆序数k,答案ans = k * min(x,y)。

由于本题数值范围[-1e9,1e9],而n最多1e5,树状数组不可能开2e9,所以只能进行离散化。

时间复杂度:sort函数O(nlogn),unique函数O(n),暴力枚举n个元素并获取ID以及树状数组修改+查询操作O(nlogn),总的O(nlogn),满足要求。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=+; struct _BIT //单点修改、区间查询
{
int n,C[maxn];
int lowbit(int x){return x&(-x);}
void init(int n)
{
this->n=n;
memset(C,,sizeof(C));
}
void add(int pos,int val) //在pos点加上val
{
while(pos<=n)
{
C[pos]+=val;
pos+=lowbit(pos);
}
}
int ask(int pos) //查询1~pos点的和
{
int ret=;
while(pos>)
{
ret+=C[pos];
pos-=lowbit(pos);
}
return ret;
}
}BIT; int n;
ll x,y; int a[maxn]; vector<int> v;
inline int getID(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+;}
int main()
{
while(scanf("%d%d%d",&n,&x,&y)!=EOF)
{
v.clear();
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end()); BIT.init(v.size());
ll cnt=;
for(int i=;i<=n;i++)
{
int id=getID(a[i]);
BIT.add(id,);
cnt+=BIT.ask(v.size())-BIT.ask(id);
} cout<<cnt*min(x,y)<<endl;
}
}

HDU 6318 - Swaps and Inversions - [离散化+树状数组求逆序数][杭电2018多校赛2]的更多相关文章

  1. SGU180 Inversions(树状数组求逆序数)

    题目: 思路:先离散化数据然后树状数组搞一下求逆序数. 离散化的方法:https://blog.csdn.net/gokou_ruri/article/details/7723378 自己对用树状数组 ...

  2. hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)

    题目链接 题意: 给一个n个数的序列a1, a2, ..., an ,这些数的范围是0-n-1, 可以把前面m个数移动到后面去,形成新序列:a1, a2, ..., an-1, an (where m ...

  3. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  4. hdu 5147 Sequence II (树状数组 求逆序数)

    题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. poj 2299 Ultra-QuickSort(树状数组求逆序数)

    链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...

  6. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

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

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

  8. Codeforces645B【树状数组求逆序数】

    题意: 给你1-n的序列,然后有k次机会的操作,每一次你可以选择两个数交换. 求一个最大的逆序数. 思路: 感觉就是最后一个和第一个交换,然后往中间逼近,到最终的序列,用树状数组求一下逆序数. #in ...

  9. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

随机推荐

  1. 微信公众号支付-Common

    using System.Web; /// <summary> /// 公共帮助类 /// </summary> public class Common { private H ...

  2. 数据注解特性--NotMapped

    NotMapped特性可以应用到领域类的属性中,Code-First默认的约定,是为所有带有get,和set属性选择器的属性创建数据列.. NotManpped特性打破了这个约定,你可以使用NotMa ...

  3. Eclipse Maven 配置setting.xml 的镜像远程仓库

    1.在.m2中新建settings.xml文件 1.window-->Preferences-->Maven-->User Settings 3.点击open file 编辑将远程仓 ...

  4. iOS开发-Autolayout小结

    昨天重点学习了下Autolayout,把以前没有吃透的概念重新理解了下,现在感觉整个人都是棒棒哒. 上一个项目是使用计算坐标代码的方式来布局UI界面,这种方式的缺点在于当苹果发布新尺寸设备时需要重写代 ...

  5. phpadmin试用

    在Windows或者Linux下mysql安装后默认的密码为空,又当我们又安装了mysql的管理工具phpmyadmin后登陆时 出现“空密码登陆呗禁止(参见允许密码为空)”.不能登录成功       ...

  6. Nginx 用户认证

    访问一些比较私密的页面 ( 如管理后台,数据后台 ) 时,我们就可以设置访问该页面时需要使用用户名和密码进行验证,这就是用户认证 [root@localhost ~]$ cat /usr/local/ ...

  7. unity2017.4.0f1使用AS3.0的AndroidSDK遇到的问题

    原因: Unity 在编译时会调用 Android SDK tools 中的 android 命令,而在新版本的 Android SDK tools 中,android这个命令已经废弃了,导致 Uni ...

  8. Flask中向前端传递或者接收Json文件的方法

    1. 利用flask的request.form.get()方法 这一中方法主要利用flask的request.form.get方法,获得前端发送给后台的json文件 Python 端代码: @app. ...

  9. React Native(三)——推送jpush-react-native

    瞬间,有种满血复活的赶脚…… 原因呢,就是熟悉了rn项目的套路:当老大问道,“推送功能看了还是没看呢?”的时候,虽然一直没有调试通,但还是不怯场的回答,“看了,按照网上说的也配了,但是还是用不了,不知 ...

  10. JavaScript的格式--从格式做起,做最严谨的工程师

    1.JavaScript的格式: JavaScript区分大小写: JavaScript脚本程序须嵌入在HTML文件中: JavaScript脚本程序中不能包含HTML标记代码:(双引号) 每行写一条 ...