题目描述

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2

其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

输入输出格式

输入格式:

输入文件为 match.in。

共三行,第一行包含一个整数 n,表示每盒中火柴的数目。

第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。

第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出格式:

输出文件为 match.out。

输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。

输入输出样例

输入样例#1:

【输入输出样例 1】
4
2 3 1 4
3 2 1 4
【输入输出样例 2】
4
1 3 4 2
1 7 2 4
输出样例#1:

【输入输出样例 1】
1
【输入输出样例 2】
2

说明

【输入输出样例说明1】

最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。

【输入输出样例说明2】

最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。

【数据范围】

对于 10%的数据, 1 ≤ n ≤ 10;

对于 30%的数据,1 ≤ n ≤ 100;

对于 60%的数据,1 ≤ n ≤ 1,000;

对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

思路:为了求最小的sigma,我们需要将每列的火柴高度有序化,此时问题就可以看成:要将火柴列A,B都转化成有序数列需要的交换次数。

那么,求有序转化的交换次数的问题,也可以看成求序列逆序对过程,而此题的难点就是需要我们求双序列逆序对。

首先解决单序列的逆序对问题,这里我考虑用我最熟悉的数据结构:树状数组(当然线段树也同样是解题利器,只不过改点求区间树状数组更简洁,优雅)。

算法过程1:利用逆序对定义「1」,数组A中,若i<j,而A[i]>A[j],则构成一对逆序对,我们可以这样设计:

确定树状数组代表的是一个数域,即数组A中元素值构成的一个区间,而维护区间中数存在的个数(想象桶排序是怎么做的?)。

从1到n遍历数组A,用A[i]的值更新数域。

因为当前树状数组中1~A[i]维护就是数组中下标小于i、且小于A[i]的数的个数,令这个数为T,所以已经纳入树状数组的数的个数i(已经更新了i个数,对吧?)-T=已经更新过却大于A[i]的数的个数S,利用「1」,得出S=当前数构成逆序对的个数。

输出S,算法完成。

其次,我们再解决双序列逆序对问题。

算法过程2:有什么想法呢?无非和数组下标和键值有关,看看题干“0 ≤火柴高度≤ maxlongint”,这就说明我们不可拿火柴高度作为树状数组下标,所以实现存下每根火柴在原数组中的下标A'和B',以火柴高度为关键字对数组A和B排一下序,根据A'为下标,把B'作为键值,放入数组C中,构成一个次序序列,再用C作为树状数组下标进行算法1操作。

问题解答完毕。

#include<cstdio>
#include<iostream>
#include<algorithm>
#define modnum 99999997
using namespace std;
int C[100001],D[100001],n,ans;
struct box{
int id,key;
bool operator<(const box h)const{
return key<h.key;
}
}A[100001],B[100001];
void read(box E[])
{
for(int i=1;i<=n;i++){
scanf("%d",&E[i].key);
E[i].id=i;
}
}
inline int lowbit(int x)
{return x&(-x);}
inline void add(int x)
{
for(int i=x;i<=n;i+=lowbit(i))
D[i]++;
}
inline int sum(int x)
{
int cnt=0;
for(int i=x;i>0;i-=lowbit(i))
cnt+=D[i];
return cnt;
}
int main()
{
scanf("%d",&n);
read(A);read(B);
sort(A+1,A+n+1);sort(B+1,B+n+1);
for(int i=1;i<=n;i++)
C[A[i].id]=B[i].id;
ans=0;
for(int i=1;i<=n;i++){
add(C[i]);
ans+=(i-sum(C[i]));
ans%=modnum;
}
printf("%d\n",ans%modnum);
return 0;
}

noip2013 火柴排队的更多相关文章

  1. LOJ2609. NOIP2013 火柴排队 【树状数组】

    LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...

  2. [树状数组+逆序对][NOIP2013]火柴排队

    火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...

  3. NOIP2013火柴排队[逆序对]

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  4. [NOIP2013] 火柴排队(归并排序)

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  5. jzoj[1438]NOIP2013火柴排队

    读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 ...

  6. noip2013火柴排队_Solution

    要想对任意(ai,bi)和(aj­和b­j),当ai<aj时,都有bi<=bj:当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1& ...

  7. NOIP2013火柴排队

    Solution 恕我直言,这题是真的坑. 对于这道题,一个很显然的思路是对于A B两个序列,他们交换完后相对的两个数在原序列中的相对大小是相同的,于是我们就把序列按照A排序,在把B离散化,求逆序对, ...

  8. NOIp2013 火柴排队【逆序对/思维】 By cellur925

    题目大意:给你两列数\(ai\)和\(bi\),你可以交换每列数中相邻的两个数,求一个最小交换次数使\(\sum_{i=1}^{n}(a_i-b_i)^2\) 最小. 最后满足条件的两个序列一定是各个 ...

  9. NOIP 2013 火柴排队

    洛谷 P1966 火柴排队 洛谷传送门 JDOJ 2227: [NOIP2013]火柴排队 D1 T2 JDOJ传送门 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高 ...

随机推荐

  1. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q88-Q91)

    Question 88  You are designing a SharePoint 2010 application that stores data in a list named Base L ...

  2. 生成iOSAPP的二维码

    1.打开iTunes,在"应用"里面搜索要找的APP 2.右键要生成二维码的APP,选择"拷贝链接" 3.百度一个二维码生成器 4.把刚才拷贝的链接粘贴进去,点 ...

  3. setRequestedOrientation设置屏幕方向

    void android.app.Activity.setRequestedOrientation(int requestedOrientation)   官方API解释:     Change th ...

  4. Android 手机卫士--九宫格使用

    本文地址:http://www.cnblogs.com/wuyudong/p/5907736.html,转载请注明源地址. 采用GridView来实现,和ListView使用方式类似,列数(3列) 首 ...

  5. [Android] android studio 2.0即时运行功能探秘

    即时运行instant Run是android studio 2中,开发人员最关心的特性之一 在google发布studio 2.0之后,马上更新体验了一把,然而发现,并没快多少,说好的即时运行呢? ...

  6. symfony2 安装并创建第一个页面

    1.安装和配置 参考 http://symfony.cn/docs/book/installation.html 使用安装工具: windows系统 Open your command console ...

  7. png-8 和 png-24的区别

    png是一种图片格式,是Portable Networks Graphics的缩写,做ping. png8和png24的区别如下. 1 "PNG8"是指8位索引色位图," ...

  8. java 某字符串在另一字符串中是否存在

    boolean a = 字符串a.contains("字符串b");

  9. [整理]PHP/HTML混写的四种方式

    PHP作为一款后端语言,为了输出给浏览器让浏览器呈现出来,无可避免的要输出HTML代码,下文介绍下我用过的三种PHP/HTML混编方法 1.单/双引号包围法 这是最初级的方法了,用法就像下面这样 &l ...

  10. Sql Server之旅——第七站 为什么都说状态少的字段不能建索引

    我们在学sqlserver的时候,大多教科书和前辈们都说状态少的字段不要建索引,由此带来的开销还不如不建索引,但是这句话有多少人真的知道, 或者说有多少人真的对此有比较深刻的理解,而不是听别人道听途说 ...