Problem Description
During Frosh Week, students play various fun games to get to know each other and compete against other teams. In one such game, all the frosh on a team stand in a line, and are then asked to arrange themselves according to some criterion, such as their height, their birth date, or their student number. This rearrangement of the line must be accomplished only by successively swapping pairs of consecutive students. The team that finishes fastest wins. Thus, in order to win, you would like to minimize the number of swaps required.
 
Input
The first line of input contains one positive integer n, the number of students on the team, which will be no more than one million. The following n lines each contain one integer, the student number of each student on the team. No student number will appear more than once. 
 
Output
Output a line containing the minimum number of swaps required to arrange the students in increasing order by student number. 
 
Sample Input
3 3 1 2
 
Sample Output
2
 
分析题意后发现是一个求逆序数的问题
给一列数A[1],A[2],…,A[n],求它的逆序数,即有多少个有序对(i,j),使得i<j但A[i]>A[j]。
受归并排序启发,用分治法解决该问题,把序列分成元素个数尽量相等的两半,递归统计i和j均在左边或者均在右边的逆序数,再统计i在左边,但j在右边的逆序数。
对于i在左边,j在右边的分类,按照j的不同把这些“跨越两边”的逆序对进行分类,只要对于右边的每个j,统计左边比它大的元素个数cnt,则所有cnt之和便是答案。归并排序时,当右边的A[j]复制到辅助数组ass中时,左边还没来得及复制到ass的那些数就是左边所有比A[j]大的数。此时cnt加上左边元素个数mid-p即可(左边所剩的元素在区间[p,mid)中,因此元素个数为mid-p)。
 
归并排序:
(1)划分问题:把序列分成元素个数尽量相等的两半。
(2)递归求解:把两半元素分别进行归并排序。
(3)合并问题:把两个有序表合并成一个。合并时每次只需要把两个序列的最小元素加以比较,删除其中的较小元素并加入合并后的新表即可。
 
注意小细节
(1)代码中使用的左闭右开区间,用左闭右开区间来表示一个范围,好处是在处理“数组分割”时比较自然,区间[low,high)被分成的是[low,mid)和[mid,high),不需要在任何地方加减1(主函数中调用时high要赋上n+1),另外,空区间表示为[x,x),比[x,x-1]顺眼多了。
(2)分界点mid=low+(high-low)/2而不是(low+high)/2,数学上两者相等,但在计算机中却有差别,运算符“/”的取整是朝零方向的取整,用low+(high-low)/2来确保分界点总是靠近区间起点(虽然在这题中并非必要),还有一点,使用mid=low+(high-low)/2还可以避免low+high在low和high很大时可能会出现的溢出。
(3)/2用>>1实现
 #include <stdio.h>
#define MAX 1000000 int arr[MAX+],ass[MAX+];
__int64 cnt; void MergeSort(int low,int high){
int mid,p,q,i;
if(high-low==)
return;
mid=low+((high-low)>>);
MergeSort(low,mid);
MergeSort(mid,high);
p=low,q=mid,i=low;
while(p<mid||q<high){
if(q>=high||(p<mid&&arr[p]<=arr[q]))
ass[i++]=arr[p++];
else{
ass[i++]=arr[q++];
cnt+=mid-p;
}
}
for(i=low;i<high;i++)
arr[i]=ass[i];
} void scani(int &num){
char ch;
int flag;
while(ch=getchar(),(ch>''||ch<'')&&(ch!='-'));
if(ch=='-')
flag=-,num=;
else
flag=,num=ch-'';
while(ch=getchar(),ch<=''&&ch>='')
num=num*+ch-'';
num*=flag;
} int main(){
int n,i;
while(~scanf("%d",&n)){
for(i=;i<=n;i++)
scani(arr[i]);
cnt=;
MergeSort(,n+);
printf("%I64d\n",cnt);
}
return ;
}

Frosh Week的更多相关文章

  1. HDU 3743 Frosh Week (线段树+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 Frosh Week Time Limit : 2000/1000ms (Java/Other) ...

  2. UVA 11858 Frosh Week 逆序对统计

    题目链接: http://acm.hust.edu.cn/vjudge/contest/122094#problem/H Frosh Week Time Limit:8000MSMemory Limi ...

  3. 暑假集训(2)第六弹 ----- Frosh Week(UVA11858)

    H - Frosh Week Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     ...

  4. 问题 C: Frosh Week(2018组队训练赛第十五场)(签到)

    问题 C: Frosh Week 时间限制: 4 Sec  内存限制: 128 MB提交: 145  解决: 63[提交][状态][讨论版][命题人:admin] 题目描述 Professor Zac ...

  5. Frosh Week(归并排序求逆序数)

    H - Frosh Week Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

  6. HDU 3743 Frosh Week(归并排序求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程 ...

  7. HDU 3743 Frosh Week(归并排序求逆序数)

    归并排序求逆序数 #include <iostream> #include <cstdio> using namespace std; #define maxn 1000005 ...

  8. Frosh Week HDU3743(逆序数)

    离散化加 求逆序数: 求逆序数的方法 一个是归并排序  一个是树状数组 #include<bits/stdc++.h> using namespace std; int n; struct ...

  9. Prerequisites?[HDU1144]

    Prerequisites?Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...

随机推荐

  1. 〖Eclipse〗Eclipse实现类似于YouCompleteMe补全插件的tab选择,shift+tab反向选择,空格、回车、点号等结束选择。

    1.增加Eclipse的提示功能 在Eclipse中,从Window -> preferences -> Java -> Editor -> Content assist -& ...

  2. QQ概念版(WPF制作)

    984 QQ概念版 编辑   QQ 概念版是腾讯首款NUI(自然用户交互)产品,全面实现了多点触摸操作.是腾讯利用微软最新一代的客户端展现层技术--WPF,打造的IM产品. 中文名 QQ 概念版 游戏 ...

  3. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 代码下载:http://www.demodashi.com/demo/10631.html 一.准备工作 需要准备一部带有温度传感 ...

  4. mysql优化之参数优化

    1.优化方式 硬件优化=>系统优化=>mysql配置优化=>SCHEMA优化=>sql优化=>其他解决方案(redis or MongoDB or Cassandra o ...

  5. JS打开新窗口防止被浏览器阻止的方法[转]

    本文实例讲述了JS打开新窗口防止被浏览器阻止的方法.分享给大家供大家参考.具体分析如下: 用传统的window.open()方式打开新窗口,会被浏览器阻止,那么,我们如何才能让JS打开新窗口不被浏览器 ...

  6. RMAN备份时报“ORA-19504: failed to create file”和“ORA-27038: created file already exists”

    RMAN> run { > allocate channel ch00 type disk; > backup format '/dbbackup/db_%T' database; ...

  7. fcntl 函数与文件锁

    一.fcntl函数 功能:操纵文件描述符,改变已打开的文件的属性 int fcntl(int fd, int cmd, ... /* arg */ ); cmd的取值可以如下: 复制文件描述符 F_D ...

  8. Python 列表 pop() 方法

    描述 Python 列表 pop() 方法通过指定元素的索引值来移除列表中的某个元素(默认是最后一个元素),并且返回该元素的值,如果列表为空或者索引值超出范围会报一个异常. 语法 pop() 方法语法 ...

  9. java使用ssh访问Linux的项目jscraft

    一.gradle地址 // https://mvnrepository.com/artifact/com.jcraft/jsch compile group: 'com.jcraft', name: ...

  10. npm 模块化方式接入 font-awsome

    https://segmentfault.com/q/1010000009795785/a-1020000009796355 $ npm install font-awesome 在main.js里添 ...