poj 2299 逆序数
http://poj.org/problem?id=2299
坑:答案是long long 输出……!!!!!
题意是:求一个数组进行冒泡排序交换的次数
题解:求逆序数
题解Ⅰ:
归并排序求逆序数
归并排序求逆序数之前写过
1.归并排序是把两个有序的数组合并成为一个有序的数组,利用分治的思想就可以进行排序
逆序数可以利用这个思想求
求出第一个数组的逆序数,和第二个数组的逆序数,再将两个数组整体的逆序数求出来
f(x,y) = f(x,mid) + f(mid,y) + 之后数组的逆序数
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <stack>
const int MAXN = + ;
const int INF = 0x7fffffff;
const int MOD = ;
const double ESP = 10e-;
const double Pi = acos(-1.0);
typedef long long LL;
using namespace std;
LL a[MAXN];
LL b[MAXN];
LL h(int s,int e){
if(e-s <= ){
return ;
}
int mid = s + (e-s)/;
LL x = h(s,mid);
LL y = h(mid,e);
int p1 = s;
int p2 = mid;
int p3 = s;
LL cnt = ;
while(p1 < mid || p2 < e){
if(p2 >= e || (p1 < mid && a[p1] < a[p2])){
b[p3++] = a[p1++];
}
else{
b[p3++] = a[p2++];
cnt += (mid-p1); /*第二个数组当前元素比第一个数组当前元素小,所以第一个数组从当前元素到最后的元素都比第二个数组的大(数组一,二都已经有序了),所以第一个数组结尾下标,减去第一个数组的当前元素就是两个数组的逆序数*/
}
}
for(int i = s;i < e;i++){
a[i] = b[i];
}
return x+y+cnt;
}
int main(){
//freopen("input.txt","r",stdin);
int n;
while(~scanf("%d",&n) && n){
for(int i = ;i < n;i++){
scanf("%d",&a[i]);
}
LL ans = h(,n);
printf("%lld\n",ans);
}
return ;
}
题解Ⅱ:
http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html
这个童鞋写得已经很棒了
1.数组元素太大,而n 的个数又很少,所以需要离散化
离散化:
用struct Node{
int v;
int order;
};
将元素读入,并且将元素的次序读入
将元素排序之后,下标的标号一定程度上是代表元素的大小
所以用下标的标号就可以表示元素
这样范围就减少了
2.
树状数组是求 前 i 个 元素的和
先 add(a[i],1)
再 i - sum(a[i])
前面已经有 i 个元素了,sum(a[i]) 表示 1 - a[i] 的和 ,而 i - sum(a[i]) 表示有多少个数字比 a[i] 大 但是 次序却在 i 位置的前面 就是 a[i] 元素的逆序数
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <stack>
const int MAXN = + ;
const int INF = 0x7fffffff;
const int MOD = ;
const double ESP = 10e-;
const double Pi = acos(-1.0);
typedef long long LL;
using namespace std;
int a[MAXN];
int bit[MAXN+];
int n;
struct Node{
int v;
int order;
bool operator < (const Node x)const{
return v < x.v;
}
};
Node in[MAXN];
int sum(int i){
int s = ;
while(i>){
s += bit[i];
i -= (i & -i);
}
return s;
}
void add(int i,int x){
while(i <= n){
bit[i] += x;
i += (i&-i);
}
}
int main(){
// freopen("input.txt","r",stdin);
while(~scanf("%d",&n) && n){
memset(bit,,sizeof(bit));
for(int i = ;i <= n;i++){
scanf("%d",&in[i].v);
in[i].order = i;
}
sort(in+,in++n);
for(int i = ;i <= n;i++){
a[in[i].order] = i;
}
LL ans = ;
for(int i = ;i <= n;i++){
add(a[i],);
ans += i-sum(a[i]);
}
printf("%lld\n",ans);
}
return ;
}
poj 2299 逆序数的更多相关文章
- POJ 2299 逆序对
Crossings Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description I ...
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...
- 逆序数 POJ 2299 Ultra-QuickSort
题目传送门 /* 题意:就是要求冒泡排序的交换次数. 逆序数:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序. 一个排列中逆序的总数就称为这个排列的逆 ...
- poj 2299 Ultra-QuickSort (归并排序 求逆序数)
题目:http://poj.org/problem?id=2299 这个题目实际就是求逆序数,注意 long long 上白书上的模板 #include <iostream> #inclu ...
- POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数
题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数)
链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...
- poj 2299 Ultra-QuickSort 归并排序求逆序数对
题目链接: http://poj.org/problem?id=2299 题目描述: 给一个有n(n<=500000)个数的杂乱序列,问:如果用冒泡排序,把这n个数排成升序,需要交换几次? 解题 ...
- poj 2299 Ultra-QuickSort :归并排序求逆序数
点击打开链接 Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 34676 Accepted ...
随机推荐
- SeekBar 样式设置
1 SeekBar简介 SeekBar是进度条.我们使用进度条时,可以使用系统默认的进度条:也可以自定义进度条的图片和滑块图片等. 2 SeekBar示例 创建一个activity,包含2个SeekB ...
- CSDN排名第一和第二的人
http://blog.csdn.net/phphot http://blog.csdn.net/yuanmeng001
- Spring IOC和DI原理讲解并制作LazyCoder版的Spring (一)
转载请注意出处:http://blog.csdn.net/zcm101 写在前面的话 最近,给项目组成员培训了Spring 控制反转和依赖注入的原理,并自己做了个Lazy Coder版的Spring, ...
- switch语句:适用于一个条件有多个分支的情况---分支语句
例1: 客服选择功能,然后按按键 Console.WriteLine("查花费请按1,查余额请按2,查流量请按3,办理业务请按4,宽带请按5,人工服务请按6,集团业务请按7"); ...
- PHP - 直接输出对象的版本问题
- ThinkPHP - 连贯操作 - 【实现机制】
<?php //模型类 class Model { //数据库连接 private $_conn = NULL; //where语句 private $_where = NULL; //表名称 ...
- Checkbox in DataList
一,效果图. 二,源代码. <!DOCTYPE html><html><head> <meta charset="UTF-8"> & ...
- iOS开发UITableViewCell的选中时的颜色设置
1.系统默认的颜色设置 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = ...
- media_root以及static_root配置
# At the top of settings/base.pyfrom os.path import join, abspath, dirnamehere = lambda *x: join(abs ...
- lucene 索引查看工具
luke 是 lucene 索引查看工具,基于 swing 开发的,是 lucene.solr.nutch 开发过程中不可或缺的工具.在测试搜索过程,进程出现搜不到东西或者搜到的东西不是想要的结果时, ...