题目大意

  涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: $\sum_{i=1}^n(a_i-b_i)^2$,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度。 每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

题解

预备知识

  • 因为任何a火柴的交换效果都与b交换火柴相同,所以我们只让b火柴移动。
  • 通过邻项交换的方法,我们可以得到一个序列的任意一个排列。

贪心

  我们让序列$b$序列变换后的结果序列称为$b'$。那么对$\forall i$,$a_i$在$a$中的大小排名与$b'_i$在$b'$中的相同。

  证明为邻项交换。如果$a_1$与$b_1$配对,$a_2$与$b_2$配对,$a_1\leq a_2, b_1 \leq b_2$,则这样得到的结果,比$a_1$和$b_2$、$a_2$和$b_1$配对得到的结果小。为了表示方便,我们令$x=a_1,y=b_1,a_2=x+k,b_2=y+t$,则前者的结果为$$(x-y)^2+(x+k-b-t)^2$$,后者结果为$$(a-b-t)^2+(a+k-b)^2$$。后者减去前者得到的结果为$$2kt$$,恒大于0。故原命题成立。

如何得到$b'$?

  $b'$的要求是如果将$a$排序的变换为$f(a)$,则$f(b')$得到的序列也是递增的。也就是说,我们要得到$b'$,要先将$b$排序得到$b''$,随后$f^{-1}(b'')=b'$。那么达到$f^{-1}$的方法便是将$a$排序后的rank为下标,原来的id为值得到一个数组,随后将每个$b''$移到对应的id位置去即可。

那么要交换多少次呢?

  即为逆序对数。用树状数组解决即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;#define ll long long
const int MAX_N = 100010;
const ll P = 99999997;
int N;
int NewId_OrgId[MAX_N];struct BIT
{
private:ll C[MAX_N];int Lowbit(int x){return x & -x;}public:void Update(int p, ll delta){while (p <= N){C[p] += delta;p += Lowbit(p);}}ll Query(int p){ll ans = 0;while (p > 0){ans += C[p];p -= Lowbit(p);}return ans;}
}g;struct Node
{int Id, Val;bool operator < (const Node &a) const{return Val < a.Val;}
}A[MAX_N], B[MAX_N], B1[MAX_N];int main()
{scanf("%d", &N);for (int i = 1; i <= N; i++)A[i].Id = B[i].Id = i;for (int i = 1; i <= N; i++)scanf("%d", &A[i].Val);for (int i = 1; i <= N; i++)scanf("%d", &B[i].Val);sort(A + 1, A + N + 1);for (int i = 1; i <= N; i++)NewId_OrgId[i] = A[i].Id;sort(B + 1, B + N + 1);for (int i = 1; i <= N; i++)B1[NewId_OrgId[i]] = B[i];ll ans = 0;for (int i = N; i >= 1; i--){ans = (ans + g.Query(B1[i].Id - 1)) % P;g.Update(B1[i].Id, 1);}printf("%lld\n", ans);return 0;
}

  

转载于:https://www.cnblogs.com/headboy2002/p/9784539.html

luogu1966 火柴排队相关推荐

  1. NOIP2013 火柴排队 [洛谷P1966]

    NOIP2013 火柴排队 [洛谷P1966] 题目描述 涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之 ...

  2. P1966 火柴排队题解

    P1966 火柴排队 题意:有两列火柴,各有各的高度,两两高度不同,每次只能交换相邻的数,问最少交换多少次,使得 ∑ ( a i − b i ) 2 \sum (a_i-b_i)^2 ∑(ai​−bi ...

  3. 【NOIP2013】【Luogu1966】火柴排队(逆序对)

    problem 给你两个长为n的序列 最小化∑ni=1(a[i]+b[i])2∑i=1n(a[i]+b[i])2 \sum_{i=1}^n(a[i]+b[i])^2的值,答案%99999997. so ...

  4. 水题 逆序对 NOIP 2013 火柴排队

    题目如下 题目描述 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: ,其中 a ...

  5. 【逆序对相关/数学】【P1966】【NOIP2013D1T2】 火柴排队

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

  6. 火柴排队(codevs 3286)题解

    [问题描述] 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴 ...

  7. 洛谷P1966 火柴排队

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

  8. 火柴排队(离散化案例+数学推导)

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

  9. 【NOIP2013提高组】火柴排队

    题目背景 NOIP2013 提高组 Day1 试题 题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定 ...

最新文章

  1. 为女儿取名“王者荣耀”可想过代价?
  2. 第二章 rabbitmq在mac上的安装
  3. 自学python3 最好的入门书籍-学习python3入门书籍选哪些?
  4. 冈萨雷斯图像处理Matlab函数汇总
  5. 公式编辑器中怎么打出分数中间的一横
  6. 怎么把mysql 查询数据_如何使用查询字符串值从数据库中查询数据
  7. 基于微信小程序的透析耗材管理系统
  8. 淘淘商城第107讲——添加购物车
  9. junit单元测试步骤
  10. 基于安卓端的背单词系统的设计与实现
  11. Google Play 开发者账号注册 上架应用
  12. oracle数据库HugePages配置
  13. python问题——ValueError: only 2 non-keyword arguments accepted
  14. RabbitMQ提示ERROR: epmd error for host
  15. LaTeX插入矩阵和方程组
  16. 玉米社:SEM竞价推广预算设置方法
  17. [转载]Linux SWAP 交换分区配置说明
  18. 【BZOJ4864】【BeiJing 2017 Wc】神秘物质(Splay)
  19. 软件需求工程 高校教学平台 需求变更控制会规程
  20. 关于Opencv 分水岭算法种子点(注水口)的选取问题

热门文章

  1. Python 删除含有文件的文件夹
  2. CCC3.0学习笔记_数字钥匙系统架构
  3. 299. 猜数字游戏。
  4. 如何制作一份合格的简历
  5. shell脚本打印三角形
  6. 手机端密码键盘(weiKeyBoard.js)
  7. 机器人走正方形c语言代码,机器人走正方形教学案例
  8. 数字正方形c语言答案,正方形练习题(含答案)
  9. SpringBoot启动监听
  10. Linux命令总结--touch命令