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. ai学习记录

    界面:多个预编辑区:制作图形,使用的图形放到工作区内,不使用在预编区.没有Ctrl/Alt+delete的概念,没有前后景颜色.新建:分辨率:矢量软件和分辨率无关: 新建时候不要勾选对齐到像素网格 存 ...

  2. BZOJ5109 CodePlus 2017大吉大利,晚上吃鸡!(最短路+拓扑排序+bitset)

    首先跑正反两遍dij求由起点/终点到某点的最短路条数,这样条件一就转化为f(S,A)*f(T,A)+f(S,B)*f(T,B)=f(S,T).同时建出最短路DAG,这样图中任何一条S到T的路径都是最短 ...

  3. JavaScript词法作用域与调用对象

    关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...

  4. noip 2011观光公交

    P1315 观光公交 95通过 244提交 题目提供者该用户不存在 标签贪心递推2011NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录   题目描述 风景迷人的小城Y 市,拥有n 个美 ...

  5. [codeforces gym Matrix God]随机矩阵乘法

    题目链接:http://codeforces.com/gym/101341/problem/I 随机真是一个神奇的方法.原本矩阵乘法是n^3的复杂度,但是这个题是让判断两个矩阵是否相等,只需要在两个矩 ...

  6. HDU4370:0 or 1(最短路)

    0 or 1 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 Description: Given a n*n matrix Cij (1< ...

  7. Create a conditional DNS forwarder on our domain.com to Amazon default DNS provider

    Backgroup: I have an AWS Managed Active Directory(domain.com). I created a DHCP options set  to my d ...

  8. python中orm框架学习

    安装sqlalchemy pip3 install sqlalchemy 创建表结构: from sqlalchemy import Column,String,create_engine from ...

  9. 【Foreign】冒泡排序 [暴力]

    冒泡排序 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 4 5 ...

  10. bzoj 2064 DP

    这道题可以抽象成两个数列,将一个数列变换为另一个 数列的代价最小 首先我们可以处理出所有的状态代表,对于每个状态 用二进制来表示,代表的是两个数列中的每一项选还是不选 那么答案最多为n1+n2-2,也 ...