NYOJ117 求逆序数
来源:互联网 发布:js 掷骰子动画 编辑:程序博客网 时间:2024/06/11 09:16
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=117
题目分析:
如果直接一个一个的找,时间复杂度是O(n^2),这道题数据量很大,这样肯定会超时的。我们肯定都之后把有序数组a和b归并成另外一个有序数组。这个思想可以用到这里来,假设需要归并的数据段是[Begin,Mid)和[Mid,End)。用i,j分别遍历两个数据段,如果后面数据段中有数据比前一个数据段中的元素小,那么它跨越的长度就是逆序对的个数,即Mid-i,i是第一个比j大的数。这里要注意,数组最大的元素个数是10^6,最多的逆序对的个数为10^12-10^6,int最大也就2*10^9。肯定会越界的,所以这里要用long long来计数。
#include<stdio.h>#include<string.h>long long Merge(int *arr, int *ans, int Begin, int Mid, int End){int i,j,k;long long count = 0;for(i = Begin, j = Mid, k = Begin; i < Mid && j < End; ++k){if(arr[i] <= arr[j])ans[k] = arr[i++];else{//数组2中跨越数组1的长度即为逆序对的个数count += Mid - i;ans[k] = arr[j++];}}for( ; i < Mid; ++i, ++k)ans[k] = arr[i];for( ; j < End; ++j, ++k)ans[k] = arr[j];memcpy(&arr[Begin], &ans[Begin], (End - Begin) * sizeof(int));return count;}long long MergeSort(int *arr, int *ans, int nLen){int i,l,e;long long count = 0;//步长跨度for(l = 1; l < nLen; l *= 2){for(i = 0; i + l < nLen; i += l + l){//第二部分的结束e = i + l + l > nLen ? nLen : i + l + l;count += Merge(arr, ans, i, i + l, e);}}return count;}int arr[1000001];int ans[1000001];int main(){int i,n,t;long long count;scanf("%d", &t);while(t--){scanf("%d",&n);for(i = 0; i < n; ++i)scanf("%d", &arr[i]);count = MergeSort(arr, ans, n);printf("%lld\n", count);}return 0;}
- NYOJ117 求逆序数
- nyoj117求逆序数
- NYOJ117求逆序数
- NYOJ117 求逆序数
- NYOJ117 求逆序数
- NYOJ117 求逆序数
- NYOJ117-求逆序数(归并排序)
- nyoj117 求逆序数 归并排序
- NYOJ117&& 树状数组求逆序数
- nyoj117 求逆序数【线段树】
- nyoj117——求逆序数
- nyoj117 求逆序数 归并排序
- nyoj117求逆序数(离散化+树状数组/归并排序)
- 树状数组(归并排序) 之 求逆序数nyoj117
- nyoj117——用归并排序求逆序数
- nyoj117求逆序数 并归排序法
- NYOJ117 求逆序数(归并排序记录次数)
- 【nyoj117】—求逆序数(归并排序)
- jQuery源码分析 (init)
- ToolBar多彩工具栏制作详细过程
- struts2 存取cookie
- 在SQL 脚本中进行 文件的读写
- ICE Manual(Documentation for Ice 3.5)---Slice
- NYOJ117 求逆序数
- Shell标准输出、标准错误 >/dev/null 2>&1
- Flyweight模式 的学习
- jQuery event 源码注释
- androidSpinner使用及根据选择项跳转到相应的Activity
- FlyWeight模式——设计模式学习笔记
- Linux Vi/Vim 键盘图
- 网页判断IE版本
- 设计模式开篇(一)