题目背景

NOIP2013 提高组 Day1 试题

题目描述

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

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

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

输入格式

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

输出格式

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

样例数据 1

输入


2 3 1 4 
3 2 1 4

输出

1

样例数据 2

输入


1 3 4 2 
1 7 2 4

输出

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≤火柴高度≤23^1-1

解析:

想错了一个地方卡了半天。。。

首先我们知道要使得原式最小,只有在两列数的第K大相互对应的时候最小(证明略)。

那么问题就转化成了:

把数列b的数字大小关系移动成数列a的大小关系所需要的最小移动次数。

如何做呢?举个例子:

3 2 4 1

2 4 1 3

现在要求最小移动次数是的数列b变为:3 2 4 1

那么说明原位置1要移动到2,2移动到3,3移动到4,4移动到1(这里的数字指位置)。对应到一个新数列中即为:

2 3 4 1

目标状态为:

1 2 3 4

那么答案就为让这个新序列有序的最小移动次数,于是就是裸的逆序对了,用树状数组或归并排序均可。

代码(归并排序):

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <cctype>
#include <ctime>
#include <queue>
using namespace std;const int Max=100105;
const int mod=99999997;
struct px{int bh,num;};
px a[Max],b[Max];
long long c[Max],r[Max];
long long n,sum;int get_int()
{int x=0,f=1;char c;for(c=getchar();(c<'0'||c>'9')&&(c!='-');c=getchar());if(c=='-') {f=-1; c=getchar();}for(;c>='0'&&c<='9';c=getchar()) x=(x<<3)+(x<<1)+c-'0';return x*f;
}bool comp(const px &a,const px &b)
{return a.num<b.num;
}void merge(int s,int mid,int t)
{int i=s,k=s,j=mid+1;while(i<=mid&&j<=t){if(c[i]>c[j]){r[k++]=c[j++];sum+=mid-i+1;}else r[k++]=c[i++];}while(i<=mid) r[k++]=c[i++];while(j<=t) r[k++]=c[j++];for(int x=s;x<=t;x++) c[x]=r[x];
}void mergesort(int s,int t)
{if(s<t){int mid=(s+t)/2;mergesort(s,mid);mergesort(mid+1,t);merge(s,mid,t);}
}int main()
{n=get_int();for(int i=1;i<=n;i++){a[i].num=get_int();a[i].bh=i;}for(int i=1;i<=n;i++){b[i].num=get_int();b[i].bh=i;}sort(a+1,a+n+1,comp);sort(b+1,b+n+1,comp);for(int i=1;i<=n;i++) c[b[i].bh]=a[i].bh;mergesort(1,n);cout<<sum%mod<<endl;return 0;
}

代码(树状数组):

#include <bits/stdc++.h>
using namespace std;const int mod=99999997;
const int Max=100005;
int n,m,tot,ans;
int sum[Max],c[Max<<1],num[Max];
struct shu{int num,id;};
shu a[Max],b[Max];inline int get_int()
{int x=0,f=1;char c;for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());if(c=='0') f=-1,c=getchar();for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';return x*f;
}inline bool comp(const shu &a,const shu &b){return a.num<b.num;}inline void pre()
{ sort(c+1,c+tot+1);m=unique(c+1,c+tot+1)-c-1;for(int i=1;i<=n;i++) a[i].num=lower_bound(c+1,c+m+1,a[i].num)-c;for(int i=1;i<=n;i++) b[i].num=lower_bound(c+1,c+m+1,b[i].num)-c;
}inline void add(int num)
{for(int i=num;i<=100000;i+=i&(-i)) sum[i]++;
}inline int Q(int num)
{int ans=0;for(int i=num;i;i-=i&(-i)) ans+=sum[i];return ans;
}inline void solve()
{for(int i=1;i<=n;i++) add(num[i]),ans=(ans+i-Q(num[i]))%mod;cout<<ans<<"\n";
}int main()
{n=get_int();for(int i=1;i<=n;i++) c[++tot]=a[i].num=get_int(),a[i].id=i;for(int i=1;i<=n;i++) c[++tot]=b[i].num=get_int(),b[i].id=i;pre();sort(a+1,a+n+1,comp),sort(b+1,b+n+1,comp);for(int i=1;i<=n;i++) num[a[i].id]=b[i].id;solve();return 0;
}

【NOIP2013提高组】火柴排队相关推荐

  1. NOIP2013 提高组复赛解题报告

    NOIP2013 提高组复赛 day1 day\;1 1002. 火柴排队 贪心+数据结构/归并排序 这个"相邻交换"让我联想到了NOIP2012_day1_task2_game那 ...

  2. 【题解】P1979 [NOIP2013 提高组] 华容道(SPFA,BFS,常数优化)

    [题解]P1979 [NOIP2013 提高组] 华容道 最近打比赛次次挂..平均每周得被至少一场比赛打击一次(这周好不容易 ABC 打的还行模拟赛又挂--)心烦意乱.写篇题解疏散一下内心的苦闷(雾) ...

  3. P1149 [NOIP2008 提高组] 火柴棒等式——暴力枚举

    [NOIP2008 提高组] 火柴棒等式 题目描述 给你 n n n 根火柴棍,你可以拼出多少个形如 A + B = C A+B=C A+B=C 的等式?等式中的 A A A. B B B. C C ...

  4. 【NOIP2013提高组】花匠

    题目背景 NOIP2013 提高组 Day2 试题. 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空 ...

  5. P1979 [NOIP2013 提高组] 华容道

    题目来源 [NOIP2013 提高组] 华容道 - 洛谷 题目考点 搜索   图论 题目 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, ...

  6. 【NOIP2013提高组】积木大赛

    题目背景 NOIP2013 提高组 Day2 试题 题目描述 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为 1  ...

  7. 【NOIP2013提高组T3】加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  8. [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)

    一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...

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

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

最新文章

  1. 02-CSS基础与进阶-day6_2018-09-05-22-02-24
  2. 安装Numpy的简单方法
  3. 使用python,爆破加密的rar压缩文件
  4. android5去wifi感叹号,android 5.1 WIFI图标上的感叹号及其解决办法
  5. 大数据测试英语水平测试
  6. 移动端+京东移动端首页制作
  7. P1458 [USACO2.1]顺序的分数 Ordered Fractions
  8. ai是个什么软件,和PS一样么
  9. Zookeeper 原理与优化
  10. LTE 各频段对应频点以及频率,频点号与频率之间的转换关系
  11. 网络舆情如何有效预警的方式方法详解
  12. 帝国CMS2018年最新漏洞获取管理员密码
  13. Auto.js实现自动解锁屏幕
  14. python练习-easygui-温度转换
  15. SQL中的行转列和列转行
  16. 学术英文 | (7) Unit3Words
  17. 教你用python进行数字化妆,可爱至极
  18. JFFS2的remount过程
  19. EM算法(一)--------------------最大似然估计
  20. 找到新硬件向导的的解决方法

热门文章

  1. 如何进行BI工具的选型?2020必看的商业智能工具选型参考
  2. VUE html5-qrcode H5扫一扫功能
  3. Schema与schema文档
  4. ctf中ASCII,base64几种密码的基本样式
  5. 仿闲鱼 底部菜单html,GitHub - 494293346/rotateMenu: 仿闲鱼首页,“底部加号弹出菜单选项” 界面,动画效果可能跟闲鱼有点不一样...
  6. oracle aq 删除,创建及删除AQ table时候报错 ORA-00955,ORA-24005,ORA-24002 - 1
  7. Web---JSTL(Java标准标签库)-Core核心标签库、I18N国际化、函数库
  8. 海牛大数据教你Hadoop 如何批量操作多台服务器
  9. YOLOX全文翻译及环境配置
  10. MEION:QAM仿真j时读不到数据的原因分析