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 ...
随机推荐
- 2015.5.2-2015.5.8 Tip jQuery ,前端组件库,inline-block元素间距等
有忙于它事,故延迟了,但在坚持! 1.Tip jQuery 2.给span加display: inline-block; 怎样能对齐? 解决方法:vertical-align: bottom: ...
- [译]Testing Node.js With Mocha and Chai
原文: http://mherman.org/blog/2015/09/10/testing-node-js-with-mocha-and-chai/#.ViO8oBArIlJ 为什么要测试? 在此之 ...
- (转载)JavaWeb学习总结(五十一)——邮件的发送与接收原理
博客源地址:http://www.cnblogs.com/xdp-gacl/p/4209586.html 一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电 ...
- 摄像头拍照,PHP输入流php://input的使用分析
在做一个摄像头拍照然后上传的功能,php中使用php://input来获取内容.于是就了解了下php://input. 从官网信息来看,php://input是一个只读信息流,当请求方式是post的, ...
- js/javascript代码注释规范与示例
文件注释 文件注释位于文件的最前面,应包括文件的以下信息:概要说明及版本(必须)项目地址(开源组件必须)版权声明(必须)开源协议(开源组件必须)版本号(必须)修改时间(必须),以ISO格式表示(可使用 ...
- css3径向渐变详解-遁地龙卷风
(-1)写在前面 我用的是chrome49,如果你用的不是.可以尝试换下浏览器前缀.IE在这方面的实现又特例独行了.不想提及-,这篇是为后续做准备. (0)快速使用 background-image: ...
- sscanf提取字符串中的数据php
1.需求 理解sscanf的作用 2.例子 $str = "age:30 weight:60kg"; sscanf($str,"age:%d weight:%dkg&qu ...
- mysql存储过程学习
一.存储过程的创建 语法: CREATE PROCEDURE sp_name (参数)合法的SQL语句 mysql> delimiter // mysql> CREATE PROCEDUR ...
- SVN 删除误上传到服务器的文件
使用Axure软件的时候,不小心把一些无用的文档也提交到了SVN上了. 当更新服务器上的文件到本地,然后删除误提交的文件时,出现了一个错误,见下图: 错误:cannot verify lock o ...
- PHP 变量声明的意义
有人说,PHP是没有类型的语言,个人比较倾向于,PHP是弱类型的计算机脚本语言的说法. 计算机存储都是二进制的数据,要么是0,要么是1. 在抽象数据的过程中,是要有各种各样的标志位来识别数据. 虽然, ...