luogu1966 火柴排队
题目大意
涵涵有两盒火柴,每盒装有 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;
}
luogu1966 火柴排队的更多相关文章
- luogu1966 火柴排队(离散化+树状数组)
由于是一个二次函数的关系,所以易证应该尽量让两组的顺序相同 然后就离散化乱搞几发,最后就变成了求逆序对的数量了 #include<bits/stdc++.h> #define pa pai ...
- $Noip2013/Luogu1966$ 火柴排队 贪心+离散化+逆序对
$Luogu$ $Description$ 给定等长的$a,b$两个序列.每次可以交换一个序列中相邻两个数.求最小的交换次数使得$\sum(a_i-b_i)^2$最小. $Sol$ 交换后的序列一定满 ...
- Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对
题目:http://codevs.cn/problem/3286/ 3286 火柴排队 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : ...
- 洛谷P1966 【火柴排队】
题解 P1966 [火柴排队] 说明: 在数学中有个公式: (a1-b1)^2+(a2-b2)^2<(a2-b1)^2+(a1-b2)^2 (你可以自己试着证一下) 两列火柴对应的两根火柴在各列 ...
- [树状数组+逆序对][NOIP2013]火柴排队
火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...
- 【刷题】洛谷 P1966 火柴排队
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
[NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...
- LOJ2609. NOIP2013 火柴排队 【树状数组】
LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...
- 洛谷 P1966 火柴排队 解题报告
P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: \(\s ...
随机推荐
- 学习 Qt 编程的好书精品推荐!
最近一段时间,准备开始搞Qt方面的东西,想找几本书看看.网上介绍QT的书籍也有很多,不想浪费时间,所以想找几本精品的书籍来看.花了半天的时间找了几本非常不错的,这里面整理好之后推荐给大家! 下面介绍的 ...
- 关于C/C++的一些思考(1)
C++的前世今生: C的结构化思想: Ada的模版思想: Fortran的运算符重载思想: Simula的OO思想:封装,继承,多态: C++类型描述了变量的三个特征: 该类型在内存中占用物理空间的大 ...
- [Python3网络爬虫开发实战] 1.7.3-Appium的安装
Appium是移动端的自动化测试工具,类似于前面所说的Selenium,利用它可以驱动Android.iOS等设备完成自动化测试,比如模拟点击.滑动.输入等操作,其官方网站为:http://appiu ...
- c语音 dll断点调试方法
转自:https://blog.csdn.net/qingzai_/article/details/45348613 dll调试方法: 1.把最新生成的dll和pdb放到 启动这个dll 的进程目录下 ...
- 最近编译POCO 库和 Boost库的笔记
最近在编译POCO库和BOOST库 先讲一下编译POCO库,我编译的是1.9.0,过程相当曲折,要OPENSSL修改版本的,个OPENSSL在这里下载,如果你用一般未修改的OPENSSL 是编译不了, ...
- [luoguP1328] 生活大爆炸版石头剪刀布(模拟)
传送门 虽然是模拟,但是我们可以用矩阵保存结果,来是其更加简便. ——代码 #include <cstdio> #include <iostream> ][] = {{, , ...
- 桐桐的糖果计划(vijos 1325)
背景 桐桐是一个快乐的小朋友,他生活中有许多许多好玩的事,让我们一起来看看吧…… 描述 桐桐很喜欢吃棒棒糖.他家处在一大堆糖果店的附近. 但是,他们家的区域经常出现塞车.塞人等情况,这导致他不得不等到 ...
- 2018/2/27 Activiti教程之创建流程篇(与Springboot整合版)一
因为电脑还在托运中,现在手上这台垃圾电脑实在是没法玩微服务,所以趁着这两天玩玩Activiti吧. 说实话,在学习Activiti中走了N多弯路,最大的原因就是网上没有一个完整(好)的教程,甚至连官方 ...
- 从零开始写STL-容器-list
从零开始写STL-容器-list List 是STL 中的链表容器,今天我们将通过阅读和实现list源码来解决一下问题: List内部的内存结构是如何实现的? 为什么List的插入复杂度为O(1)? ...
- easyUi 学习笔记 (二 ) 使用tabs 里datagridview 发送ajax请求 不访问后台的问题
这个BUG 我花了一个半小时, 还是看不出哪里的问题, 于是就百度到这么一段话,我需要记住 <================================================= ...