HDU 3743 Frosh Week (线段树+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743
Frosh Week
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 5 Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
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
题解:
/*本题给定一个数n,然后给出n个数的序列,
要求最少交换多少次可使原序列变成递增的。
根据以往的经验,也就是求序列的逆序数的和。
可用线段树破之。
但本题有个陷阱,即原序列中的n个数并没说是从1到n的某个排列。
对此我们可以先进行离散化。离散化在本题很简单,
只需记录数在原序列中的下标,然后按数值从小到大排序。
排序后的下表id对应该数在原数组中的相对大小,
然后我们按从小到大的顺序插入,查询。*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int MAXN=+;
struct node
{
int num,id;
}Per[MAXN]; int C[MAXN];
int Lowbit[MAXN]; //C[i] = a[i-lowbit(i)+1] + …+ a[i],下表从1开始
//Lowbit[i]=i&(i^(i-1));或Lowbit[i]=i&(-i);
//1.查询 int QuerySum(int p)
//查询原数组中下标1-p的元素的和
{
int nSum=;
while(p>)
{
nSum+=C[p];
p-=Lowbit[p];
}
return nSum;
} //2.修改+初始化
void Modify(int p,int val)
//原数组中下表为p的元素+val,导致C[]数组中部分元素值的改变
{
while(p<=MAXN-)
{
C[p]+=val;
p+=Lowbit[p];
}
}
//********************************************** bool cmp(node a,node b)
{
return a.num<b.num;
} int main()
{
int n,i;
__int64 ans;
for(i=;i<MAXN;i++)
Lowbit[i]=i&(-i);
while(~scanf("%d",&n))
{
for(i=;i<=n;i++)
//scanf("%d",&da[i]);
{
scanf("%d",&Per[i].num);
Per[i].id=i;
}
memset(C,,sizeof(C));
ans=;
sort(Per+,Per+n+,cmp);
for(i=;i<=n;i++)
{
ans+=(__int64)QuerySum(n)-(__int64)QuerySum(Per[i].id);
Modify(Per[i].id,);
}
printf("%I64d\n",ans);
}
return ;
}
ps:本来是在树状数组专题做的题目,结果自己写了好几次 RE MLT WA 各种错误都出现过 还是没有A掉 无语了
下面是我的错误代码 请无视 谢谢 囧
/*自己的错误代码 0.0*/
/*re mlt wa 好无语*/
#include<iostream> using namespace std ; const int MAXN=+; int sum[MAXN];
int n ; int lowbit(int x) //取x的最低位1,比如4,则返回4,如5,则返回1
{
return x&(-x);
} void update(int i, int val) //将第i个元素增加val
{
//i的祖先都要增加val
while(i <= n)
{
sum[i] += val;
i += lowbit(i); //将i的二进制未位补为得到其祖先
}
} int Sum(int i) //求前i项的和
{
int s = ;
//将前i项分段
while(i > )
{
s += sum[i];
i -= lowbit(i); //去掉i的二进制最后一个
}
return s;
} int main()
{
int i;
int a[],b[];
while(scanf("%d",&n)!=EOF)
{
int count=;
memset(b,,sizeof(b));
memset(sum,,sizeof(sum));
for(i=;i<=n;i++)
{
scanf("%d",&a[i]);
} for(i=;i<=n; i++)
{
b[i] = Sum(a[i]); //求前a[i]项的和
update(a[i],); //第a[i]个元素+1
count+=i-b[i]-;
} cout<<count<<endl; } return ;
}
HDU 3743 Frosh Week (线段树+离散化)的更多相关文章
- HDU - 1542 扫描线入门+线段树离散化
扫描线算法+线段树维护简介: 像这种求面积的并集的题目,就适合用扫描线算法解决,具体来说就是这样 类似这种给出点的矩形的对角的点的坐标,然后求出所有矩形面积的交集的问题,可以采用扫描线算法解决.图如下 ...
- 【HDU】5249-KPI(线段树+离散化)
好久没写线段树都不知道怎么写了... 很easy的线段树二分问题 #include<cstdio> #include<set> #include<queue> #i ...
- HDU 4288 Coder 【线段树+离线处理+离散化】
题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...
- HDU5124:lines(线段树+离散化)或(离散化思想)
http://acm.hdu.edu.cn/showproblem.php?pid=5124 Problem Description John has several lines. The lines ...
- POJ 2528 Mayor's posters(线段树+离散化)
Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...
- poj 2528 Mayor's posters(线段树+离散化)
/* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...
- [poj2528] Mayor's posters (线段树+离散化)
线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...
- [UESTC1059]秋实大哥与小朋友(线段树, 离散化)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...
- poj 2528 Mayor's posters 线段树+离散化技巧
poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
随机推荐
- SearchLookUpEdit
参考资料: 慧都控件网-DevExpress开发资源 在GridControl控件中使用SearchLookUpEdit构建数据快速输入
- 如何处理 在html中 li 的高度自适应(且li里面的内容有浮动的情况下)
废话不多说,我们写贴出代码 这个是 Html 代码 <div class="main"> <ul> <li> <div class=&qu ...
- ActiveMQ支持的传输协议
------------------------------------------------------ ActiveMQ支持的client-broker通讯协议有:TCP.NIO.UDP.SSL ...
- JDBC ODBC区别
一.JDBC(Java DataBase Connectivity standard) 1.JDBC,它是一个面向对象的应用程序接口(API), 通过它可访问各类关系数据库. 2. 驱动程序(JDBC ...
- Coursera-Getting and Cleaning Data-week1-课程笔记
博客总目录,记录学习R与数据分析的一切:http://www.cnblogs.com/weibaar/p/4507801.html -- Sunday, January 11, 2015 课程概述 G ...
- css中为了清除浮动经常用到的after样式
.cf:after { display: block; visibility: hidden; width:; height:; line-height:; font-size:; clear: bo ...
- iOS开发——高级篇——iOS中如何选择delegate、通知、KVO(以及三者的区别)
在开发IOS应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers[B]怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信:1委托delegation2通知 ...
- what's cloud computing? IaaS
Cloud computing has changed the ITC industry. Companies like Amazon, Google and Microsoft have built ...
- WIN7下VS2008生成Detours3.0
Detours是微软开发的一个函数库,可用于捕获系统API.在用其进行程序开发之前,得做一些准备工作: 一.下载Detours 在http://research.microsoft.com ...
- [Linux]Linux系统调用列表
本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...