题目传送门

 /*
题意:就是要求冒泡排序的交换次数。
逆序数:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。
一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。
如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。也是就说,对于n个不同的元素,
先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,
当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。 接下来有多种做法求解逆序数:1. 暴力;2. 归并排序;3. 线段树-单点更新;4. 树状数组
*/

 /*
暴力 超时 O(n^2)
*/
#include <stdio.h> const int MAX_N = ;
int a[MAX_N+];
long long cnt = ; int main(void) //POJ 2299 Ultra-QuickSort
{
//freopen ("inD.txt", "r", stdin);
int n; while (scanf ("%d", &n) != EOF && n)
{
for (int i=; i<=n; ++i)
{
scanf ("%d", &a[i]);
} for (int i=; i<=n; ++i)
{
for (int j=i+; j<=n; ++j)
{
if (a[i] > a[j])
cnt++;
}
}
printf ("%lld\n", cnt);
cnt = ;
} return ;
}

暴力 超时 O(n^2)

 /*
归并排序是将数列a[p, r]分成两半a[p, q]和a[q+1,r]分别进行归并排序,
然后再将这两半合并起来。在合并的过程中(设p<=i<=q,q+1<=j<=r),
当L[i]<=R[j]时,并不产生逆序数;
当L[i]>R[j]时,在前半部分中比L[i]大的数都比R[j]大,
将R[j]放在L[i]前面的话,逆序数要加上q+1-i。
因此,可以在归并排序中的合并过程中计算逆序数。 这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在:)
*/
#include <stdio.h> const int MAX_N = ;
const int INF = 0xffffff;
int a[MAX_N+];
long long cnt = ; void Merge(int *a, int p, int q, int r)
{
int n1 = q - p + ;
int n2 = r - q;
int L[MAX_N/+], R[MAX_N/+];
int i, j;
for (i=; i<=n1; ++i) L[i] = a[p+i-];
for (j=; j<=n2; ++j) R[j] = a[q+j];
L[n1+] = INF; R[n2+] = INF; i = ; j = ;
for (int k=p; k<=r; ++k)
{
if (L[i] <= R[j])
{
a[k] = L[i++];
}
else
{
a[k] = R[j++];
cnt += n1 - i + ; //此步骤是在归并排序法中加的一句,用来计数求逆序数的数目
}
}
} void MergeSort(int *a, int p, int r)
{
int q;
if (p < r)
{
q = (p + r) / ;
MergeSort (a, p, q);
MergeSort (a, q+, r);
Merge (a, p, q, r);
}
} int main(void) //POJ 2299 Ultra-QuickSort
{
//freopen ("inD.txt", "r", stdin);
int n; while (scanf ("%d", &n) != EOF && n)
{
for (int i=; i<=n; ++i)
{
scanf ("%d", &a[i]);
}
MergeSort (a, , n);
printf ("%lld\n", cnt);
cnt = ;
} return ;
}

归并排序

 /*
线段树-单点更新
*/
#include <cstdio>
#include <algorithm>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1
using namespace std; const int MAX_N = ;
const int INF = 0x3f3f3f3f;
int a[MAX_N];
int b[MAX_N];
int sum[MAX_N << ]; 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);
} int query(int ql, int qr, int l, int r, int rt)
{
if (ql <= l && r <= qr)
{
return sum[rt];
}
int m = (l + r) >> ;
int ans = ;
if (ql <= m) ans += query (ql, qr, lson);
if (qr > m) ans += query (ql, qr, rson); return ans;
} int BinarySearch(int key, int l, int r)
{
while (r >= l)
{
int mid = (l + r) >> ;
if (key == b[mid]) return mid;
if (key < b[mid]) r = mid - ;
else l = mid + ;
}
} int main(void)
{
//freopen ("inD.txt", "r", stdin);
int n;
while (~scanf ("%d", &n) && n)
{
build (, n-, ); for (int i=; i<=n; ++i)
{
scanf ("%d", &a[i]);
b[i] = a[i];
}
sort (b+, b+n+);
long long ans = ;
for (int i=; i<=n; ++i)
{
int x = BinarySearch (a[i], , n);
ans += query (x, n, , n, );
update (x, , n, );
}
printf ("%lld\n", ans);
} return ;
}

线段树-单点更新

逆序数 POJ 2299 Ultra-QuickSort的更多相关文章

  1. 归并排序求逆序对(poj 2299)

    归并排序求逆序对 题目大意 给你多个序列,让你求出每个序列中逆序对的数量. 输入:每组数据以一个数 n 开头,以下n行,每行一个数字,代表这个序列: 输出:对于输出对应该组数据的逆序对的数量: 顺便在 ...

  2. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  3. poj 2299 Ultra-QuickSort (归并排序 求逆序数)

    题目:http://poj.org/problem?id=2299 这个题目实际就是求逆序数,注意 long long 上白书上的模板 #include <iostream> #inclu ...

  4. POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

    题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...

  5. poj 2299 逆序数

    http://poj.org/problem?id=2299 坑:答案是long long 输出……!!!!! 题意是:求一个数组进行冒泡排序交换的次数 题解:求逆序数 题解Ⅰ: 归并排序求逆序数 归 ...

  6. poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...

  7. poj 2299 Ultra-QuickSort(树状数组求逆序数)

    链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...

  8. poj 2299 Ultra-QuickSort 归并排序求逆序数对

    题目链接: http://poj.org/problem?id=2299 题目描述: 给一个有n(n<=500000)个数的杂乱序列,问:如果用冒泡排序,把这n个数排成升序,需要交换几次? 解题 ...

  9. poj 2299 Ultra-QuickSort :归并排序求逆序数

    点击打开链接 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 34676   Accepted ...

随机推荐

  1. LVS负载均衡集群服务搭建详解(一)

    LVS概述 1.LVS:Linux Virtual Server 四层交换(路由):根据请求报文的目标IP和目标PORT将其转发至后端主机集群中的某台服务器(根据调度算法): 不能够实现应用层的负载均 ...

  2. 将服务器上的myql数据库导入本地数据库

    文章是从我的个人博客上粘贴过来的, 大家也可以访问 www.iwangzheng.com 首先登录到服务器上,进入文件夹,我们这边的是m-cms $mysqldump -uroot mos > ...

  3. RO05 - 如何编写RemObjects SDK服务端 (Delphi Version)

    转载:http://blog.csdn.net/henreash/article/details/2261134 本文档向你展示如何使用RemObjects(Delphi版)创建第一个服务.读了本文档 ...

  4. POJ 1251 Jungle Roads (prim)

    D - Jungle Roads Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Su ...

  5. 谷歌、百度、1万ip能赚多少钱?1000IP能够值多少钱呢?

    谷歌.百度.1万ip能赚多少钱?1000IP能够值多少钱呢? (2014-04-03 11:50:52) 转载▼ 标签: 广告联盟 百度联盟 谷歌联盟 ip赚钱       很多在人问:谷歌.百度:1 ...

  6. jQuery Ajax 操作函数

    jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. 函数 描述 jQuery.ajax() 执行异步 H ...

  7. 56. 2种方法判断二叉树是不是平衡二叉树[is balanced tree]

    [本文链接] http://www.cnblogs.com/hellogiser/p/is-balanced-tree.html [题目] 输入一棵二叉树的根结点,判断该树是不是平衡二叉树.如果某二叉 ...

  8. 【HTTP协议】响应头中的Content-Length和Transfer-Encoding

    来源: http://blog.csdn.net/superhosts/article/details/8737434 http://bbs.csdn.net/topics/390384017 对于h ...

  9. osg事件处理器osgGA::GUIEventHandler handle

    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { osgViewer::View ...

  10. Auguse 2nd, Week 32nd Tuesday, 2016

    Love me little and love me long.不求情意绵绵,但愿天长地久. Friends are relatives you make for yourself.朋友是你自己结交的 ...