博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「UVA10810」Ultra-QuickSort 解题报告
阅读量:4343 次
发布时间:2019-06-07

本文共 1334 字,大约阅读时间需要 4 分钟。

看不懂?!

大概的意思就是:

给出一个长度为n的序列,然后每次只能交换相邻的两个数,问最小需要几次使序列严格上升

不断读入n,直到n=0结束

思路:

交换相邻的两个数,这不就类似冒泡排序吗?但是n<500000

算了吧,我回去颓A+B

于是我们就发现用冒泡排序直接计算次数是行不通的

但我们要知道:

冒泡排序的交换次数就是序列的逆序对数!!!

所以——就简单了吧~

如何求逆序对?

1、归并排序

思想是分治法

不断划分为两小段

然后依次由小序列合并为大序列,同时求出逆序数

2、树状数组

因为树状数组的修改查询是log级的所以可以使用(前缀和的方法),没学的建议先去学习一下,不是很难

Code:

#include
#define ll long longusing namespace std;struct node{ int x,i;}a[500010];int n;int b[500010];int f[500010];ll ans;int read(){ int s=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { s=(s<<1)+(s<<3)+c-'0'; c=getchar(); } return s;}void update(int x)//修改{ for(;x<=n;x+=x&(-x)) f[x]++; return;}ll sum(int x)//求前缀和{ ll res=0; for(;x;x-=x&(-x)) res+=f[x]; return res;}bool cmp(node a,node b){ return a.x>b.x;}int main(){ int i,j; n=read(); while(n) { ans=0; memset(f,0,sizeof(f)); for(i=1;i<=n;i++) { a[i].x=read(); a[i].i=i; } sort(a+1,a+n+1,cmp); for(i=1;i<=n;i++)//先hash一下,按数值给其标记,方便后面求逆序对 b[a[i].i]=i; for(i=1;i<=n;i++) { update(b[i]);//一步一做 ans+=sum(b[i]-1); } printf("%lld\n",ans); n=read(); } return 0;}

转载于:https://www.cnblogs.com/hovny/p/10133179.html

你可能感兴趣的文章
[原创]一篇无关技术的小日记(仅作暂存)
查看>>
20145303刘俊谦 Exp7 网络欺诈技术防范
查看>>
原生和jQuery的ajax用法
查看>>
iOS开发播放文本
查看>>
20145202马超《java》实验5
查看>>
JQuery 事件
查看>>
main(argc,argv[])
查看>>
第四阶段 15_Linux tomcat安装与配置
查看>>
NAS 创建大文件
查看>>
学习笔记-模块之xml文件处理
查看>>
接口测试用例
查看>>
Sybase IQ导出文件的几种方式
查看>>
案例:手动输入一个字符串,打散放进一个列表,小写字母反序 大写字母保持不变...
查看>>
linux 系统下 tar 的压缩与解压缩命令
查看>>
阿里负载均衡,配置中间证书问题(在starcom申请免费DV ssl)
查看>>
转:How to force a wordbreaker to be used in Sharepoint Search
查看>>
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>
设计原理+设计模式
查看>>