Swaps and Inversions

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2315    Accepted Submission(s): 882

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 [−109,109]. 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
 
Source
 
题目意思:
给你一个长度为n的数列
开始检查,如果某两个数不是从小大大顺序的,有一个就罚x元,
或者也可以直接在检查之前对不符合要求的调换位置(相邻的)
花费y元
然后要你求最小的花费
所以就是直接求这个序列的逆序数然后乘以x和y花费中较小的一个
逆序数可以归并或者数状数组求解
 
方法1归并:
#include<stdio.h>
#include<memory>
#include<algorithm>
#define max_v 100005
using namespace std;
typedef long long LL;
LL a[max_v];
LL temp[max_v];
LL ans;
void mer(int s,int m,int t)
{
int i=s;
int j=m+;
int k=s;
while(i<=m&&j<=t)
{
if(a[i]<=a[j])
{
temp[k++]=a[i++];
}else
{
ans+=j-k;//求逆序数
temp[k++]=a[j++];
}
}
while(i<=m)
{
temp[k++]=a[i++];
}
while(j<=t)
{
temp[k++]=a[j++];
}
}
void cop(int s,int t)
{
for(int i=s;i<=t;i++)
a[i]=temp[i];
}
void megsort(int s,int t)
{
if(s<t)
{
int m=(s+t)/;
megsort(s,m);
megsort(m+,t);
mer(s,m,t);
cop(s,t);
}
}
int main()
{
int n;
LL c1,c2;
while(~scanf("%d %lld %lld",&n,&c1,&c2))
{
if(n==)
break;
ans=;
for(int i=;i<n;i++)
scanf("%lld",&a[i]);
megsort(,n-);
printf("%lld\n",ans*min(c1,c2));
}
return ;
}
/*
题目意思:
给你一个长度为n的数列
开始检查,如果某两个数不是从小大大顺序的,有一个就罚x元,
或者也可以直接在检查之前对不符合要求的调换位置(相邻的)
花费y元
然后要你求最小的花费
所以就是直接求这个序列的逆序数然后乘以x和y花费中较小的一个
逆序数可以归并或者数状数组求解
*/

方法二:

直接树状树组加离散化

离散化其实就是数据范围压缩!!!,注意理解

#include<queue>
#include<set>
#include<cstdio>
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define max_v 500005
int n;
struct node
{
int v;
int pos;
} p[max_v];
int c[max_v];
int re[max_v];
int maxx;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int d)
{
while(x<max_v)
{
c[x]+=d;
x+=lowbit(x);
}
}
int getsum(int x)//返回1到x中小与等于x的数量
{
int res=;
while(x>)
{
res+=c[x];
x-=lowbit(x);
}
return res;
}
bool cmp(node a,node b)
{
if(a.v!=b.v)
return a.v<b.v;
else
return a.pos<b.pos;
}
int main()
{
long long c1,c2;
while(~scanf("%d %lld %lld",&n,&c1,&c2))
{
if(n==)
break;
memset(c,,sizeof(c));
for(int i=;i<=n;i++)
{
scanf("%d",&p[i].v);
p[i].pos=i;
} sort(p+,p++n,cmp); long long ans=;
for(int i=;i<=n;i++)
{
ans+=(i-getsum(p[i].pos)-);//先找再更新,避免getsum的时候算上自己
update(p[i].pos,);
}
printf("%lld\n",ans*min(c1,c2));
}
return ;
}
[ Copy to Clipboard ] [ Save to File]

HDU 6318 Swaps and Inversions 思路很巧妙!!!(转换为树状数组或者归并求解逆序数)的更多相关文章

  1. HDU 6318 - Swaps and Inversions - [离散化+树状数组求逆序数][杭电2018多校赛2]

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6318 Problem Description Long long ago, there was an ...

  2. [HDU 6318] Swaps and Inversions

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6318 [算法] 线段树 / 树状数组 [代码] #include<bits/stdc++.h ...

  3. HDU 6318 Swaps and Inversions(归并排序 || 树状数组)题解

    题意:一个逆序对罚钱x元,现在给你交换的机会,每交换任意相邻两个数花钱y,问你最少付多少钱 思路:最近在补之前还没过的题,发现了这道多校的题.显然,交换相邻两个数逆序对必然会变化+1或者-1,那我们肯 ...

  4. HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...

  5. HDU 6203 ping ping ping(dfs序+LCA+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连 ...

  6. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  7. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  8. HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle  Accepts: 42  Submissions: 26 ...

  9. HDU 4750 Count The Pairs ★(图+并查集+树状数组)

    题意 给定一个无向图(N<=10000, E<=500000),定义f[s,t]表示从s到t经过的每条路径中最长的边的最小值.Q个询问,每个询问一个t,问有多少对(s, t)使得f[s, ...

随机推荐

  1. 微信小程序之雪碧图(css script)

    今天有朋友问我关于微信小程序中如何在不占用大量网络带宽的情况下快速加载图片,我给他推荐了两种方式 1.雪碧图(css script),有过前端经验的朋友应该都有接触过. 2.懒加载. 由于时间关系我就 ...

  2. 百万级数据 MySQL处理(转)

    转自 http://www.cnblogs.com/win7xt/p/3156334.html 使用MySQL处理百万级以上数据时,不得不知道的几个常识   最近一段时间参与的项目要操作百万级数据量的 ...

  3. python代码打包发布

    背景 本文介绍了python中一种最简单的代码结构的打包方式 包名称 我们先给我们的包取个名字,python包起名需要符合下面的规范 全部小写 在pypi上是唯一的 下划线分隔或没有单词分隔符(不要使 ...

  4. TensorFlow分布式部署【多机多卡】

    让TensorFlow们飞一会儿 前一篇文章说过了TensorFlow单机多卡情况下的分布式部署,毕竟,一台机器势单力薄,想叫兄弟们一起来算神经网络怎么办?我们这次来介绍一下多机多卡的分布式部署. 其 ...

  5. BadgeView使用

    BadgeView是第三方的插件,用来显示组件上面的标记,起到提醒的作用,下载地址如下:http://files.cnblogs.com/files/hyyweb/android-viewbadger ...

  6. SpringBoot 之HelloController

    1.搭建环境 1.1 新建一个maven项目,一路下一步 1.2 打开pom 文件,首先增加<parent></parent>标签: <parent> <gr ...

  7. beautifulsoup之CSS选择器

    BeautifulSoup支持大部分的CSS选择器,其语法为:向tag或soup对象的.select()方法中传入字符串参数,选择的结果以列表形式返回. tag.select("string ...

  8. Vue2学习笔记:实例生命周期

    实例生命周期 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 DOM .在这个 ...

  9. 制作 OS X El Capitan 启动盘

    制作 OS X El Capitan 启动盘 1. 下载系统盘的dmg格式 2. 直到出现了 3. 在命令行中找到 Install OS X El Capitan.app 4. 格式化你的U盘(U盘名 ...

  10. mysql数据库配置文件

    一.数据库配置文件 数据库配置文件是很一个很强大的功能,这是数据库管理员经常需要关注的配置文件. my.ini  #这是在windows下的配置文件名称. my.conf  #这是在linux下的配置 ...