惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - Franky
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
J
Java Code Geeks
F
Full Disclosure
V
V2EX
The Register - Security
The Register - Security
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
Help Net Security
Help Net Security
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
博客园 - 聂微东
Recorded Future
Recorded Future
I
Intezer
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
H
Hacker News: Front Page
SecWiki News
SecWiki News
M
MIT News - Artificial intelligence
Security Latest
Security Latest
Attack and Defense Labs
Attack and Defense Labs
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
T
Tenable Blog
B
Blog
N
News | PayPal Newsroom
P
Proofpoint News Feed
D
Docker
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
C
Cisco Blogs
A
Arctic Wolf
T
Threat Research - Cisco Blogs
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
GbyAI
GbyAI
P
Palo Alto Networks Blog
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
Latest news
Latest news
Project Zero
Project Zero

hsfzxjy 的博客

解决 VSCode + CMake + MSVC 编译器信息乱码的问题 使用 3090 部署 1.58bit 动态量化版 DeepSeek R1 671b 如何在 VS Code DevContainer 中配置 HTTP 代理 如何在跳板机背后的服务器上使用 VS Code Remote - Containers Cohesive Digests for Ints and Floats Rust 中的隐匿概念 —— Place(位置) 美术馆 一尺之槌,日取其半,1075日而竭 老生常谈:使用 Cloudflare 自选 IP 加速站点访问 辩义 State、Nation 与 Country 将 Base64 编码的数据快速转换为 Uint8Array 折腾 NPU·第1章 —— 搭建 Level Zero 开发环境 折腾 NPU·第0章 —— Intel NPU 概述与 Level-Zero 新增域名 monad.run CSS 中为特定字符设置不同字体 Arbitary Lifetime Transmutation via Rust Unsoundness Dijkstra 算法的延伸 Manacher 回文计数算法 硬卧 Go Fact: Zero-sized Field at the Rear of a Struct Has Non-zero Size Display *big.Rat Losslessly and Smartly in Golang 代码的仪式 Building Electron From Scratch 中式亲属称谓研究之一:构建半群 Some Notes on Kotlin Coroutines Git sparse-checkout and partial clones for Mega-Repos 辩义“封建” Diving from the CUDA Error 804 into a bug of libnvidia-container Modern Cryptography, GPG and Integration with Git(hub) Move the Root Partition of Ubuntu A New Programmer Kicks a Roadblock Git-based Dependencies in Dart and Go Reversy Naming 人类一败涂地 Invalid Golang Pointers Can Bite You Even If You Don't Dereference Side Project(副业) A Flaw of Promoting Complex Trait Bounds in Rust Initialize Process Pool Worker with Individual Value Rust - Python FFI From Scratch [Extending Hexo For My Site] Part 1 [Extending Hexo For My Site] Part 0 Debug a 'torch.tensor(1).cuda()' hanging 不自由的互联网 Retrieve Contents over HTTP without curl or wget [Unravelling mocona] Part 1 - Verbosity or Anti-Pattern [Unravelling mocona] Part 0 - Preface Understanding pickle in Python Rough Notes on Deploying Vaultwarden & NextCloud Bookmarks 语言狂热者与实用主义者 Demystify the randomness in CUDA kernels Performant Bulk Mutations in IndexedDB Auto Rebuild .pyx Files with pyximport Cython and Threads Obtain a Random Available TCP Port with Bash Information Theory: KL Divergence Information Theory: Entropy and Mutual Information 铁板烧 西郊线 Proof of the Gumbel Max Trick Option::as_ref Rc, RefCell and Interior Mutability Visualizing Correlation 三月十日杂感 三月一日杂感 二月十一日杂感 一月二十六日杂感 SS Configuration 一月七日杂感 四月·病 Haskell 笔记:State Monad Haskell 笔记:Monad 引论 Haskell 笔记:Applicative Haskell 笔记:Category Theory and Functor Haskell 笔记:data, type, newtype Haskell 笔记:folds 使用 Aria2 在 Ubuntu 中下载百度云资源 从伪并行的 Python 多线程说起 一个 Reentrant Error 引发的对 Python 信号机制的探索和思考 Linux 文件权限 HSFZMUN 4.0 部署小记 午后雨·科大 最后的雨夜·广州 揭秘·变态的平方根倒数算法 神坑·Python 装饰类无限递归 Python“黑魔法”之 Encoding & Decoding Ubuntu 重新映射键盘布局 为什么我要翻墙 Python“黑魔法”之 Generator Coroutines 数学美 之 判断线段相交的最简方法 除夕杂感 17 行代码实现的简易 Javascript 字符串模板 Python“黑魔法”之 Meta Classes 诗集 生活,需要被“发现” 家书·十八岁成人礼 炫技?还是需求? 【译】响应式图片的现状 【译】“为什么有这么多的编程语言?” Wisecity 商赛总结——也谈前端自动化测试 记一次 DoS 诈骗网站的经历
NOIP2013 Day1 火柴排队:快速求逆序对
2014-10-26 · via hsfzxjy 的博客

题目

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

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

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

分析

这真是一道好题——断断续续想了几天才完全 AC。

事实上,由排序不等式可知:

$$当 a_i, b_i 从小到大排序时,距离最小$$

这是一个重要的信息。因此,我们只需把 $a_i,b_i$ 进行排序,并把对应项“捆绑”成一项,再按 $a_i$ 原有的顺序进行复原,此时,可以得到由 $b_i$ 原先的下标组成的一个序列。也就是说,我们要求 $1,2,\ldots,n$ 至少经过多少步才能变为该序列。这可以用逆序对来解决。

只可惜,传统的逆序对算法时间复杂度为 $O(n^2)$,这里 $n$ 可达 $200000$,一定会超时 1。因此我们需寻求更好的算法。

用归并排序求逆序对

在归并排序的过程中,有一个步骤称为合并。在这个步骤中,需要轮流判断左右区间的第一个数的大小关系。注意到:左右区间已经有序,从而若左区间的第一个数大于右区间的第一个数,则左区间之后的所有数都大于右区间的第一个数,从而我们可以在合并时做一些修改:

procedure nx(l, r: longint);
var
mid, i, j, k: longint;
begin
if l = r then
begin
tmp[l] := a[l];
exit;
end;
mid := (l + r) shr 1;
nx(l, mid);
nx(mid+1, r);
i := l;
j := mid+1;
k := l;
while k <= r do
begin
if (j>r) or (i<=mid) and (a[i]<=a[j]) then
begin
tmp[k] := a[i];
inc(i);
end
else
begin
cnt := cnt + mid - i + 1;
tmp[k] := a[j];
inc(j);
end;
inc(k);
end;
for i := l to r do
a[i] := tmp[i];
end;

这个算法复杂度为$O(n\log n)$,是一种比较理想的算法,实现起来也简单。但他有个缺点:会打乱原数组顺序

原题代码


const
MODN = 99999997;
type
rec = record value, index: longint; end;
TArr = array [1..100000] of rec;
var
n: longint;
a, b, c, tmp: TArr;
ok: Boolean;
l, r, i, j: longint;
cnt: int64;

procedure sort(var arr: TArr; l, r: longint);
var
i, j: longint;
m, t: rec;
begin
i := l;
j := r;
m := arr[(i+j) shr 1];
repeat
while arr[i].value < m.value do inc(i);
while arr[j].value > m.value do dec(j);
if i <= j then
begin
t := arr[i];
arr[i] := arr[j];
arr[j] := t;
inc(i);
dec(j);
end;
until i >j;
if i < r then sort(arr, i, r);
if l < j then sort(arr, l, j);
end;

procedure nx(l, r: longint);
var
mid, i, j, k: longint;
begin
if l = r then
begin
tmp[l] := c[l];
exit;
end;
mid := (l + r) shr 1;
nx(l, mid);
nx(mid+1, r);
i := l;
j := mid+1;
k := l;
while k <= r do
begin
if (j>r) or (i<=mid) and (c[i].index<=c[j].index) then
begin
tmp[k] := c[i];
inc(i);
end
else
begin
cnt := cnt + mid - i + 1;
cnt := cnt mod MODN;
tmp[k] := c[j];
inc(j);
end;
inc(k);
end;
for i := l to r do
c[i] := tmp[i];
end;

begin
assign(input, 'main.in'); reset(input);
assign(output, 'main.out'); rewrite(output);

readln(n);
for i := 1 to n do
begin
read(a[i].value);
a[i].index := i;
end;
for i := 1 to n do
begin
read(b[i].value);
b[i].index := i;
end;
sort(a, 1, n);
sort(b, 1, n);

for i := 1 to n do
c[a[i].index] := b[i];

cnt := 0;
nx(1, n);
writeln(cnt);

close(input); close(output);
end.

作者:hsfzxjy
链接:
许可:CC BY-NC-ND 4.0.
著作权归作者所有。本文不允许被用作商业用途,非商业转载请注明出处。