FZU2018级算法第五次作业 m_sort(归并排序或线段树求逆序对)
首先对某人在未经冰少允许情况下登录冰少账号原模原样复制其代码并且直接提交的赤裸裸剽窃行为,并且最终被评为优秀作业提出抗议!
题目大意:
给一个数组含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(归并排序或线段树求逆序对)的更多相关文章
- FZU2018级算法第五次作业 missile(排序+枚举)
在解题报告之前,首先对同一次作业中另外一题(求逆序对)某人在未经冰少允许情况下,擅自登录冰少账号,原模原样剽窃冰少代码,并且最终还被评为优秀作业的行为表示严正抗议! 题目大意: 二维平面上给出 n 个 ...
- 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 题目分析: 假设目 ...
- 求逆序对常用的两种算法 ----归并排 & 树状数组
网上看了一些归并排求逆序对的文章,又看了一些树状数组的,觉得自己也写一篇试试看吧,然后本文大体也就讲个思路(没有例题),但是还是会有个程序框架的 好了下面是正文 归并排求逆序对 树状数组求逆序对 一. ...
- FZU2018级算法第一次作业 1.1fibonacci (矩阵快速幂)
题目 Winder最近在学习fibonacci 数列的相关知识.我们都知道fibonacci数列的递推公式是F(n)=F(n-1)+F(n-2)(n>=2 且n 为整数). Winder想知道的 ...
- FZU2018级算法第二次作业 2.10 逆序数(权值线段树)
题目: Nk 最近喜欢上了研究逆序数,给出一个由 1…n 组成的数列 a1,a2,a3…an, a1的逆序数就是在 a2…an 中,比 a1 小的数的数量,而 a2 的逆序数就是 a3….an 中比 ...
- 2016级算法第五次上机-F.ModricWang的水系法术
1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...
- 2016级算法第五次上机-E.AlvinZH的学霸养成记IV
1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...
- 2016级算法第五次上机-C.Bamboo和"Coco"
1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...
- 2016级算法第五次上机-B.Bamboo&APTX4844魔发药水
Bamboo&APTX4844魔发药水 题意 "于是,Bamboo耐着性子,看巫师从袖子里掏出 M 瓶时光泉水和 K 粒绿色能量.每瓶时光泉水重量为 c ,生发效果为 l:每粒绿色能 ...
随机推荐
- Redis哨兵日志说明
一.说明
- 如何在wcf中用net tcp协议进行通讯
快速阅读 如何在wcf中用net tcp协议进行通讯,一个打开Wcf的公共类.比较好好,可以记下来. 配置文件中注意配置 Service,binding,behaviors. Service中配置en ...
- sql查询性能调试,用SET STATISTICS IO和SET STATISTICS TIME---解释比较详细
一个查询需要的CPU.IO资源越多,查询运行的速度就越慢,因此,描述查询性能调节任务的另一种方式是,应该以一种使用更少的CPU.IO资源的方式重写查询命令,如果能够以这样一种方式完成查 ...
- linux下anaconda使用教程
安装Anaconda.在命令行输入,下载anaconda.wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh. ...
- Thingsboard Gateway开发环境
源码下载地址:https://github.com/thingsboard/thingsboard-gateway 国内大神源码地址:https://github.com/guodaxia103/th ...
- (信贷风控八)行为评分卡模型(B卡)的介绍
python信用评分卡建模(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_ca ...
- TextFX Notepad++
textFx Notepad++ - 国内版 Bing https://cn.bing.com/search?FORM=U227DF&PC=U227&q=textFx+Notepad% ...
- System.MarshallByRefObject.cs
ylbtech-System.MarshallByRefObject.cs 允许在支持远程处理的应用程序中跨应用程序域边界访问对象. 1.返回顶部 1. #region 程序集 mscorlib, V ...
- C/C++如何监测内存泄漏
C/C++如何监测内存泄漏 C/C++内存泄漏及检测 内存溢出就是内存越界.内存越界有一种很常见的情况是调用栈溢出(即stackoverflow),虽然这种情况可以看成是栈内存不足的一种体现.例如:递 ...
- IDEA中spring约束文件报红 的解决办法