6318.Swaps and Inversions

这个题就是找逆序对,然后逆序对数*min(x,y)就可以了。

官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可。

求逆序对有4种操作,线段树 、BIT、归并排序、树状数组。

我敲了线段树、归并排序和树状数组版的。

关于这几种方法求逆序对,自行百度吧,懒了。。。

代码(线段树版-注意排序):

 //1010-找逆序对数-线段树求逆序对数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double eps=1e-;
const int maxn=1e5+;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[maxn<<]; void PushUp(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void build(int l,int r,int rt)
{
sum[rt]=;
if(l==r){
return ;
} int m=(l+r)>>;
build(lson);
build(rson);
PushUp(rt);
} void update(int p,int l,int r,int rt)
{
if(l==r){
sum[rt]++;
return ;
} int m=(l+r)>>;
if(p<=m)update(p,lson);
else update(p,rson);
PushUp(rt);
} ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
return sum[rt];
}
int m=(l+r)>>;
ll ret=;
if(L<=m) ret+=query(L,R,lson);
if(R> m) ret+=query(L,R,rson);
return ret;
} int a[maxn],b[maxn];
int main()
{
int n,x,y;
while(~scanf("%d%d%d",&n,&x,&y)){
build(,n,);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+,b+n+);
int len=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++){
a[i]=upper_bound(b+,b+len+,a[i])-b-;
} ll sum=;
for(int i=;i<=n;i++){
sum+=query(a[i]+,n,,n,);
update(a[i],,n,);
}
printf("%lld\n",sum*min(x,y));
}
return ;
}

代码(归并排序版):

 //1010-6318-求逆序对数-归并排序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cassert>
using namespace std;
typedef long long ll;
const int maxn=1e5+;
const int inf=0x3f3f3f3f; int a[maxn],tmp[maxn];
ll ans; void Merge(int l,int m,int r)
{
int i=l;
int j=m+;
int k=l;
while(i<=m&&j<=r){
if(a[i]>a[j]){
tmp[k++]=a[j++];
ans+=m-i+;
}
else{
tmp[k++]=a[i++];
}
}
while(i<=m) tmp[k++]=a[i++];
while(j<=r) tmp[k++]=a[j++];
for(int i=l;i<=r;i++)
a[i]=tmp[i];
} void Merge_sort(int l,int r)
{
if(l<r){
int m=(l+r)>>;
Merge_sort(l,m);
Merge_sort(m+,r);
Merge(l,m,r);
}
} int main()
{
int n,x,y;
while(~scanf("%d%d%d",&n,&x,&y)){
memset(a,,sizeof(a));
memset(tmp,,sizeof(tmp));
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
ans=;
Merge_sort(,n);
printf("%lld\n",ans*min(x,y));
}
}

可以去看一下ACdreamer的博客。

代码(离散化+树状数组):

 //1010-6318-求逆序对-离散化+树状数组版
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<cassert>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1e5+; int tree[maxn];
int n; int lowbit(int x)
{
return x&(-x);
} void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i)){
tree[i]+=val;
}
} ll getsum(int x)
{
ll ans=;
for(int i=x;i>;i-=lowbit(i)){
ans+=tree[i];
}
return ans;
} int a[maxn],b[maxn];
map<int,int> mp; int main()
{
int x,y;
while(~scanf("%d%d%d",&n,&x,&y)){
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+,b++n);
int num=;
mp.clear();
for(int i=;i<=n;i++)
mp[b[i]]=num++;
for(int i=;i<=n;i++)
a[i]=mp[a[i]];
memset(tree,,sizeof(tree));
ll ans=;
for(int i=n;i>;i--){
ans+=getsum(a[i]-);
update(a[i],);
}
printf("%lld\n",ans*min(x,y));
}
return ;
}

就这样吧,溜了。

啊啊啊啊,cf又掉分了༼༎ຶᴗ༎ຶ༽

HDU 6318.Swaps and Inversions-求逆序对-线段树 or 归并排序 or 离散化+树状数组 (2018 Multi-University Training Contest 2 1010)的更多相关文章

  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 (线段树求逆序对数)

    Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. HDU 6318 Swaps and Inversions 思路很巧妙!!!(转换为树状数组或者归并求解逆序数)

    Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

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

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

  5. [HDU 6318] Swaps and Inversions

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

  6. 【a703】求逆序对(线段树的解法)

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 给定一个序列a1,a2...an.如果存在i小于j 并且ai大于aj,那么我们称之为逆序对,求给定序列中逆序 ...

  7. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  8. poj2299树状数组入门,求逆序对

    今天入门了树状数组 习题链接 https://blog.csdn.net/liuqiyao_01/article/details/26963913 离散化数据:用一个数组来记录每个值在数列中的排名,不 ...

  9. codeforces 459D D. Pashmak and Parmida's problem(离散化+线段树或树状数组求逆序对)

    题目链接: D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megab ...

随机推荐

  1. JAXB使用方式

    JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向 ...

  2. 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组

    题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000).  ...

  3. 正式进军Matlab图像处理

    Matlab取整函数有:fix, floor, ceil, round,具体应用方法如下: 1. fix朝零方向取整,如fix(-1.3) = -1; fix(1.3) = 1; 2. floor顾名 ...

  4. Hadoop上配置Hbase数据库

    已有环境: 1. Ubuntu:14.04.2 2.jdk: 1.8.0_45 3.hadoop:2.6.0 4.hBase:1.0.0 详细过程: 1.下载最新的Hbase,这里我下载的是hbase ...

  5. CF763B Timofey and Rectangles

    题目戳这里. 首先答案肯定是YES,因为一个平面图肯定可以被4种颜色染色,关键是怎么输出方案. 由于4是一个特殊的数字\(4 = 2^2\),而我们还有一个条件就是边长为奇数,而奇数是会改变二进制位的 ...

  6. 12.25模拟赛T2

    https://www.luogu.org/blog/a23333/post-xing-xuan-mu-ni-sai-path-ji-wang-zui-duan-lu 如果设f[i]表示从i到n的期望 ...

  7. vector 进阶

    http://classfoo.com/ccby/article/jnevK #include <iostream> #include <vector> #include &l ...

  8. webpack 3.8 使用 extract-text-webpack-plugin 3.0 抽取css失败:You may need an appropriate loader to handle this file type.

    webpack 3.8.1 使用 extract-text-webpack-plugin 3.0.2 抽取css时失败,报错: ERROR in ./src/static/style/localTim ...

  9. POI2007 MEG-Megalopolis [树状数组]

    MEG-Megalopolis 题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the ...

  10. Codeforces Round #526 (Div. 2) E. The Fair Nut and Strings

    E. The Fair Nut and Strings 题目链接:https://codeforces.com/contest/1084/problem/E 题意: 输入n,k,k代表一共有长度为n的 ...