集训队专题(9)1003 Frosh Week
2016-03-11 14:22
507 查看
Frosh Week
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2565 Accepted Submission(s): 851
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
Source
University of Waterloo Local Contest 2010.10.02
此题从题意上因为要我们求区间和,很容易想到的是用树状数组,本是一道痕水的题,但是由于我们树状数组全是由下标1开始(注意!不是0,如果有0在我们的函数中会出现死循环)的数组,但这题的数据并不是这样的,不过并没有关系,仔细观察你会发现,其实这里的数据并不需要它具体的值,我们需要知道的仅仅是它们相互之间的大小关系,所以我们采取对数据的离散化,以便我们用到树状数组,可能很多童鞋又要问小编数据的离散化是什么意思0.0……数据的离散化在这里说白了,就是按照大小关系重新对数据从1开始进行赋值,只有这样我们才能用我们喜欢(小编假设大家跟小编一样0.0)的树状数组。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #define LL __int64 using namespace std; const int maxn = 1000005; int a[maxn],n; struct node { int num,id; }ch[maxn]; int cmp1(node a,node b) { return a.num < b.num; } int cmp2(node a,node b) { return a.id < b.id; } int Lowbit(int k) { return k&(-k); } void update(int k,int x) { while(k <= n) { a[k] += x; k += Lowbit(k); } } int getsum(int x) { int sum = 0; while(x > 0) { sum += a[x]; x -= Lowbit(x); } return sum; } int main() { int i; LL ans; while(scanf("%d",&n)!=EOF) { ans = 0; memset(a,0,sizeof(a)); for(i=1; i<=n; i++) { scanf("%d",&ch[i].num); ch[i].id = i; } sort(ch+1,ch+n+1,cmp1);//数据的离散化 ch[1].num = 1; for(i=2; i<=n; i++) { if(ch[i].num != ch[i-1].num) ch[i].num = i; else ch[i].num = ch[i-1].num; } sort(ch+1,ch+1+n,cmp2); for(i=1; i<=n; i++) { update(ch[i].num,1); ans += (getsum(n) - getsum(ch[i].num)); } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- 自定义listview实现下拉刷新的效果
- Jira每次登录显示验证码
- setContentView方法无效
- Package:cvuqdisk-1.0.9-1
- spring框架里面的注入?
- html5的技术要点
- 了解iOS上的可执行文件和Mach-O格式
- Linux服务器硬件运行状态及故障邮件提醒的监控脚本分享
- 开源项目网站推荐
- Office10和mathType
- Linux Makefile中*.d依赖文件及 gcc -M -MF -MP等相关选项说明
- Spring+SprinMVC配置学习总结
- IIS安装教程
- 菜鸟学开店—自带U盘的打印机
- JRE与JVM、JDK的区别
- 四种方案解决ScrollView嵌套ListView问题
- BZOJ 2067 POI 2004 SZN 树形DP 贪心 二分答案
- Eclipse+ADT+Android SDK 搭建安卓开发环境
- swift开发笔记22 在表格的单元格中实现条件跳转
- win7出现黄色小叹号怎么拍错思路