P1966 火柴排队

题目描述

涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: \(\sum (a_i-b_i)^2\)其中 \(a_i\) 表示第一列火柴中第 \(i\) 个火柴的高度, \(b_i\) 表示第二列火柴中第 \(i\) 个火柴的高度。

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

输入输出格式

输入格式:

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

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

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

输出格式:

一个整数,表示最少交换次数对 \(99,999,997\) 取模的结果。

数据范围

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

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

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

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


感觉蛮神奇的一道题目。

玩一下我们感觉,两边第\(i\)大的相互对着是最优的。

证明可以先拆平方,然后利用邻项交换证明最优性。

离散一下,我们发现其实就是求逆序对。

处理起来可能比较麻烦,但把所有数组都搞出来反而不容易错。


Code:

#include <cstdio>
#include <algorithm>
#define ll long long
const int N=100010;
struct node
{
int pos;ll h;
bool friend operator <(node n1,node n2)
{
return n1.h<n2.h;
}
}a[N],b[N];
ll s[N],c[N],d[N],e[N],f[N],ans;
int n;
ll query(int x)
{
ll sum=0;
while(x)
{
sum+=s[x];
x-=x&-x;
}
return sum;
}
void add(int x)
{
while(x<=n)
{
s[x]++;
x+=x&-x;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i].h);
a[i].pos=i;
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i].h);
b[i].pos=i;
}
std::sort(a+1,a+1+n);
std::sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
c[a[i].pos]=i;
d[b[i].pos]=i;
}
for(int i=1;i<=n;i++)
e[d[i]]=i;
for(int i=1;i<=n;i++)
f[i]=e[c[i]];
for(int i=1;i<=n;i++)
{
(ans+=query(n)-query(f[i]))%=99999997;
add(f[i]);
}
printf("%lld\n",ans);
return 0;
}

2018.8.5

洛谷 P1966 火柴排队 解题报告的更多相关文章

  1. [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)

    [NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...

  2. 【刷题】洛谷 P1966 火柴排队

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

  3. 洛谷——P1966 火柴排队&&P1774 最接近神的人_NOI导刊2010提高(02)

    P1966 火柴排队 这题贪心显然,即将两序列中第k大的数的位置保持一致,证明略: 树状数组求逆序对啦 浅谈树状数组求逆序对及离散化的几种方式及应用 方法:从前向后每次将数插入到bit(树状数组)中, ...

  4. 洛谷P1966 火柴排队 贪心+离散化+逆序对(待补充QAQ

    正解: 贪心+离散化+逆序对 解题报告: 链接在这儿呢quq 这题其实主要难在想方法吧我觉得?学长提点了下说用贪心之后就大概明白了,感觉没有很难 但是离散化这里还是挺有趣的,因为并不是能很熟练地掌握离 ...

  5. [洛谷P1966] 火柴排队

    题目链接: 火柴排队 题目分析: 感觉比较顺理成章地就能推出来?似乎是个一眼题 交换的话多半会往逆序对上面想,然后题目给那个式子就是拿来吓人的根本没有卵用 唯一的用处大概是告诉你考虑贪心一波,很显然有 ...

  6. 洛谷 P1966 火柴排队

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

  7. 洛谷 P1966 火柴排队 —— 思路

    题目:https://www.luogu.org/problemnew/show/P1966 首先,一个排列相邻交换变成另一个排列的交换次数就是逆序对数: 随便画一画,感觉应该是排个序,大的对应大的, ...

  8. 洛谷——P1966 火柴排队

    https://www.luogu.org/problem/show?pid=1966 题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列 ...

  9. 洛谷p1966 火柴排队 (逆序对变形,目标排序

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

随机推荐

  1. Error -26377: No match found for the requested parameter

    Error -26377: No match found for the requested parameter

  2. Selenium(Python) ddt读取MySQL数据驱动

    import unittestfrom time import sleep from ddt import ddt, datafrom pymysql import connectfrom selen ...

  3. Jquery获取DOM绑定事件

    获取到当前正在执行的事件: $('#testDive').bind('click', function(event){alert('event: ' + event.type)}); 获取所有绑定事件 ...

  4. Git 新建文件并提交

    1.创建一个readme.txt. cd /home/cyp/learngit touch readme.txt vim readme.txt 编写内容, wq 保存推出 2.提交步骤 2.1  gi ...

  5. Spring Cloud(七):配置中心(Git 版与动态刷新)【Finchley 版】

    Spring Cloud(七):配置中心(Git 版与动态刷新)[Finchley 版]  发表于 2018-04-19 |  更新于 2018-04-24 |  Spring Cloud Confi ...

  6. es6从零学习(五):Module的语法

    es6从零学习(五):Module的语法 ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量 一:es6模块化和 CommonJS 和 AMD 模块 (运行 ...

  7. mysql 复杂查询

    1.同一个表下多次查询: sql语句: select b.* ,(select name from exh_common.medicine_type a where b.p_id = a.id) as ...

  8. TCP/IP 三次握手四次挥手

    TCP运输连接 TCP连接建立过程中要解决以下三个问题: (1)要使每一方能够确知双方的存在. (2)要允许双方协商一些参数(如最大窗口值.是否使用窗口扩大选项和时间戳选项以及服务质量等). (3)能 ...

  9. lintcode-32-最小子串覆盖

    最小子串覆盖 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 注意事项 如果在source中没有这样的子串,返回"" ...

  10. centOS6.5如何从启动界面直接进入命令行界面

    进入系统后,按Ctrl+Alt+Fn可以切换控制台,其中F1~F6是字符控制台,F7~F12是X控制台 如果启动直接进入字符控制台,而不是X Window,可以编辑/etc/inittab将id:5: ...