首先对某人在未经冰少允许情况下登录冰少账号原模原样复制其代码并且直接提交的赤裸裸剽窃行为,并且最终被评为优秀作业提出抗议!

题目大意:

  给一个数组含n个数(1<=n<=5e5),求使用冒泡排序为递增序列时,最少交换次数为多少次。

题目分析:

  对于数组中任意两个数,若$i<j$且$ai>aj$,则ai与aj必然会进行交换使其变为顺序,因此只需要求逆序对数量即可。

  分享两种方法,第一种使用归并排序:

  对于数组进行递归分治,使用归并排序,在数组两侧合并的过程中,若右侧元素先入数组,则左侧剩余元素均比该元素小,因此可以在归并排序的过程中将逆序对数量求出。

  下面分享代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn=5e5+;
int arrcy[maxn],lef[maxn],rig[maxn];
ll ans=; void mergesort(int *,int ,int);
void merge(int *,int ,int,int); int main()
{
int n,i;
scanf("%d",&n);
for (i=;i<n;i++) scanf("%d",&arrcy[i]);
mergesort(arrcy,,n-);
printf("%lld\n",ans);
return ;
} void mergesort(int arrcy[],int l,int r)
{
if(l<r)
{
int m=(l+r)/;
mergesort(arrcy,l,m);
mergesort(arrcy,m+,r);
merge(arrcy,l,m,r);
}
return ;
} void merge(int arrcy[],int l,int m,int r)
{
int num1=m-l+,num2=r-m;
int i,j;
for (i=;i<num1;i++) lef[i]=arrcy[l+i];
for (i=;i<num2;i++) rig[i]=arrcy[m++i];
i=,j=;
for (int k=;k<r-l+;k++)
{
if(i>=num1||(j<num2&&lef[i]<=rig[j]))
{
arrcy[l+k]=rig[j++];
}
else
{
if(num2>j)
ans+=num2-j;
arrcy[l+k]=lef[i++];
}
}
}

  方法二:树状数组或线段树

  先将数组按大小进行离散化排序,从大到小,对于每个元素记录其位置,然后按数组元素大小从大到小,将其原始位置+1,后续操作时先计算1至该元素位置的和,即为与该元素的逆序对数量,进行求和即可。

  分享线段树代码:

  

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int,int> pii;
#define rep(i,x,y) for(int i=x;i<y;i++)
#define rept(i,x,y) for(int i=x;i<=y;i++)
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define dd(x) cout<<#x<<"="<<x<<" ";
#define de(x) cout<<#x<<"="<<x<<"\n";
#define mes(a,b) memset(a,b,sizeof a) const int maxn=5e5+;
pii arrcy[maxn];
class Tree
{
public:
int l,r;
ll sum;
}tree[maxn<<]; void build(int id,int l,int r);
void add(int id,int p,ll num);
ll query(int id,int l,int r); bool comp(const pii &s1,const pii &s2)
{
return s1.fi>s2.fi||(s1.fi==s2.fi&&s1.se>s2.se);
} int main()
{
int n;
scanf("%d",&n);
rept(i,,n)
{
arrcy[i].se=i;
scanf("%d",&arrcy[i].fi);
}
build(,,n);
ll ans=;
sort(arrcy+,arrcy++n,comp);
rept(i,,n)
{
ans+=query(,,arrcy[i].se);
add(,arrcy[i].se,);
}
printf("%lld\n",ans);
return ;
}
void build(int id,int l,int r)
{
tree[id].l=l;
tree[id].r=r;
tree[id].sum=;
if(l==r) return ;
int mid=(l+r)/;
build(id*,l,mid);
build(id*+,mid+,r);
}
void add(int id,int p,ll num)
{
if(tree[id].l>=p&&tree[id].r<=p)
{
tree[id].sum+=num;
return ;
}
if(tree[id].l>p||tree[id].r<p) return ;
if(tree[id*].r>=p) add(id*,p,num);
if(tree[id*+].l<=p) add(id*+,p,num);
tree[id].sum=tree[id*].sum+tree[id*+].sum;
} ll query(int id,int l,int r)
{
if(tree[id].l>=l&&tree[id].r<=r) return tree[id].sum;
if(tree[id].l>r||tree[id].r<l) return ;
ll s=;
if(tree[id*].r>=l) s+=query(id*,l,r);
if(tree[id*+].l<=r) s+=query(id*+,l,r);
return s;
}

FZU2018级算法第五次作业 m_sort(归并排序或线段树求逆序对)的更多相关文章

  1. FZU2018级算法第五次作业 missile(排序+枚举)

    在解题报告之前,首先对同一次作业中另外一题(求逆序对)某人在未经冰少允许情况下,擅自登录冰少账号,原模原样剽窃冰少代码,并且最终还被评为优秀作业的行为表示严正抗议! 题目大意: 二维平面上给出 n 个 ...

  2. FZU2018级算法第三次作业 3.16 station

    题目大意: 给出1-n共n个数的入栈顺序,可以随时出栈,求出栈的最大字典序. 输入示例 输出示例 51 2 3 4 5 5 4 3 2 1 54 2 5 3 1 5 3 2 4 1 题目分析: 假设目 ...

  3. 求逆序对常用的两种算法 ----归并排 & 树状数组

    网上看了一些归并排求逆序对的文章,又看了一些树状数组的,觉得自己也写一篇试试看吧,然后本文大体也就讲个思路(没有例题),但是还是会有个程序框架的 好了下面是正文 归并排求逆序对 树状数组求逆序对 一. ...

  4. FZU2018级算法第一次作业 1.1fibonacci (矩阵快速幂)

    题目 Winder最近在学习fibonacci 数列的相关知识.我们都知道fibonacci数列的递推公式是F(n)=F(n-1)+F(n-2)(n>=2 且n 为整数). Winder想知道的 ...

  5. FZU2018级算法第二次作业 2.10 逆序数(权值线段树)

    题目: Nk 最近喜欢上了研究逆序数,给出一个由 1…n 组成的数列 a1,a2,a3…an, a1的逆序数就是在 a2…an 中,比 a1 小的数的数量,而 a2 的逆序数就是 a3….an 中比 ...

  6. 2016级算法第五次上机-F.ModricWang的水系法术

    1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...

  7. 2016级算法第五次上机-E.AlvinZH的学霸养成记IV

    1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...

  8. 2016级算法第五次上机-C.Bamboo和"Coco"

    1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...

  9. 2016级算法第五次上机-B.Bamboo&APTX4844魔发药水

    Bamboo&APTX4844魔发药水 题意 "于是,Bamboo耐着性子,看巫师从袖子里掏出 M 瓶时光泉水和 K 粒绿色能量.每瓶时光泉水重量为 c ,生发效果为 l:每粒绿色能 ...

随机推荐

  1. [C++] wchar_t关键字使用方法

    char 是单字符类型,长度为一个字节 wchar_t 是宽字符类型,长度为两个字节,主要用在国际 Unicode 编码中 举例: #include<iostream> using nam ...

  2. python反射hasattr getattr setattr delattr

    反射 : 是用字符串类型的名字 去操作 变量 相比于用eval('print(name)') 留有 安全隐患 反射 就没有安全问题 hasattr 语法: hasattr(object, name)o ...

  3. NGUI: Next-Gen UI 2018.3.0f

    https://assetstore.unity.com/packages/tools/gui/ngui-next-gen-ui-2413 NGUI is a very powerful UI sys ...

  4. 远程桌面工具mRemoteNG与Tsmmc

    一.Tsmmc.msc远程管理工具.1.下载链接:https://pan.baidu.com/s/1tV_xP-ITWyKKzAxLSlGxlw 密码:0jrt 将目录下的mstsmhst.dll.m ...

  5. SSM项目启动报错WEB-INF\lib\javax.servlet-api-4.0.1.jar) - jar not loaded. See Servlet Spec 3.0, section 10

    错误信息: validateJarFile(D:\tomcat_ryxunit\webapps\ryx_unit\WEB-INF\lib\javax.servlet.jar) - jar not lo ...

  6. 手写HashMap实践

    1.什么是HashMap 2.源码分析 3.手写实现 4.不足 一.什么是HashMap hash散列 将一个任意长度通过某种算法(hash函数算法)换成一个固定值 map: 地图x,y 存储 总结: ...

  7. markdown2的key

    分享一个MarkDown2的授权key   邮箱地址: Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGIm ...

  8. PostgreSQL中的 时间格式转化常识

    下面的SQL文查询结果是 "2018-08-20 10:09:10.815125",并且返回类型可以当String处理.返回json等都方便使用. SQL> SELECT t ...

  9. Flutter 中AlertDialog确认提示弹窗

    import 'package:flutter/material.dart'; import 'dart:async'; enum Action { Ok, Cancel } class AlertD ...

  10. org.openqa.selenium.WebDriverException: unknown error: call function result missing 'value'

    原因:浏览器和驱动版本不匹配 https://npm.taobao.org/mirrors/chromedriver