前言

\(2024.10.19\) 日校测 \(T4\),思维太庙,被薄纱了,遂哭弱,写题解以记之。

简要题意

给你一个长度为 \(2n\) 的序列满足 \(\forall a_i\in[1,n]\),其中 \(1\) 到 \(n\) 每个数都出现了两次,现在需要把相同的两个数排到一起,每次操作只能交换相邻两个数,在保证操作次数最小的情况下求出现在序列的最小字典序

数据范围:\(1\le n\le2\times10^5\)。

思路

做题的时候首先应该考虑题目性质,可以从手玩样例开始。因为最后并没有让你求最少操作次数,所以我们只用讨论数与数之间的关系。我们考虑最简单的情况:假设现在序列中只有 \(1\) 和 \(2\) 各两个,一共存在六种可能的情况。我们先将他们列出来:

  1. \(1122\)
  2. \(1212\)
  3. \(1221\)
  4. \(2112\)
  5. \(2121\)
  6. \(2211\)

对于第一种和第六种情况我们可以不用考虑,因为需要保证操作数最小。然后这四种情况实际只有两种本质不同,我们将他们抓出来。假设有两数 \(A,B\) 位置关系如下:

  • \(ABAB\)
  • \(ABBA\)

对于第一个情况,我们只需将中间两数交换即可。而第二种,我们既可以将第一个数交换到第三个位置,也可以将最后一个数交换到第二个位置。也就是说:第一种情况下数的位置决定最后顺序;而第二种情况下数的大小决定了最后顺序。

现在考虑扩展这两种情况,对于数列中任意的两数 \(A,B\),如果满足 \(A\dots B\dots A\dots B\) 的形式,我一定会让 \(A\) 排在 \(B\) 前面;如果满足 \(A\dots B\dots B\dots A\) 的形式,我就会去考虑两个数之间的大小关系。

总结一下:

\(\forall x\in[1,n]\),设 \(a_x\) 表示其第一次出现的位置,\(b_x\) 表示第二次出现的位置,如满足偏序:\(a_i\le a_j,b_i\le b_j\) 则 \(i\) 在 \(j\) 之前。所以把这些偏序抽象成一张图跑拓扑排序,拓扑时让数字小的点尽量先跑就能满足第二种情况。

可是直接建图跑是 \(O(n^2)\) 的,考虑优化。我们把每一个关于 \(i\) 的二元组 \((a_i,b_i)\) 看成平面内的点,若 \(i,j\) 之间连边则需要满足上述偏序。我们可以考虑分治建图,也就是类似 \(\text{cdq}\) 的过程,具体见下图:

我们横着切一刀把平面分成两部分,在分割线上建一些虚点。对于下面的实点垂直向上连边,上面的实点从下面虚点往上连边,然后虚点之间从左往右连。若每次在中间切最多切出 \(\log n\) 层,所以只有 \(n\log n\) 个点和边。但是拓扑的时候如果用优先队列是两只 \(\log\) 的,考虑继续优化。

其实我们只需要对实点用优先队列,对于虚点我们不关心他们的具体顺序,所以开一个普通队列存虚点,另一个优先队列存实点,每次先把所有普通队列的点拓扑完再去拓扑优先队列就行。时间复杂度是 \(O(n\log n)\) 的,因为实点只有 \(n\) 个。

代码

void cdq(int l, int r){
if(l == r)return; int mid = l + r >> 1, lim = a[mid].l;
cdq(l, mid), cdq(mid + 1, r);
int i = l, j = mid + 1, k = l;
while(i <= mid and j <= r)a[i].r < a[j].r ? b[k++] = a[i++] : b[k++] = a[j++];
while(i <= mid)b[k++] = a[i++]; while(j <= r)b[k++] = a[j++];
for(int i = l; i <= r; ++i){
a[i] = b[i], ++nd; if(i ^ l)e[nd - 1].pb(nd), ++in[nd];
if(a[i].l <= lim)e[a[i].id].pb(nd), ++in[nd];
else e[nd].pb(a[i].id), ++in[a[i].id];
}
}
void upd(int x){
if(in[x])return;
x <= n ? q.push(x) : qc.push(x);
} signed main(){
freopen("swap.in", "r", stdin);
freopen("swap.out", "w", stdout);
n = rd(), nd = n << 1;
for(int i = 1; i <= nd; ++i){
int x = rd();
if(a[x].l)a[x].r = i; else a[x].l = i, a[x].id = x;
}
sort(a + 1, a + 1 + n); nd = n;
cdq(1, n);
for(int i = 1; i <= nd; ++i)upd(i);
while(! q.empty() or ! qc.empty()){
while(! qc.empty()){
int u = qc.front(); qc.pop();
for(int v : e[u])--in[v], upd(v);
}
if(q.empty())return 0;
int u = q.top(); q.pop();
pc(u), putchar(' '), pc(u), putchar(' ');
for(int v : e[u])--in[v], upd(v);
}
return 0;
}

ARC165F题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 【C#】【报错解决】找不到请求的Net Framework Data ProVider。可能没有安装。

    如题报错截图如上,解决方法如下 第一步:找到[引用]中的MySql.Data中的版本号 第二步,在Web.config中添加如下配置 <system.data> <DbProvide ...

  2. Linux 添加开机自启动

    rc.local 方式 一.& 在 Linux 命令后加上 &  可以在后台运行 二.nohup 对 SIGHUP 信号免疫,对 SIGINT 信号不免疫,可用 shopt | gre ...

  3. 抛出 NoClassDefFoundError: javax/validation/constraints/Size 问题的解决方法

    Error:java: java.lang.NoClassDefFoundError: javax/validation/constraints/Size 问题很明显,找不到相关类.我们可以在 pom ...

  4. 一次 Spring 扫描 @Component 注解修饰的类坑

    问题现象 之前遇到过一个问题,在一个微服务的目录下有相同功能 jar 包的两个不同的版本,其中一个版本里面的类有 @Component 注解,另外一个版本的类里面没有 @Component 注解,且按 ...

  5. Qt编写可视化大屏电子看板系统22-平滑曲线图

    一.前言 平滑曲线是所有涉及到曲线图的项目中,绕不开的一个话题,尽管很多人爱看折线图,但是很多时候来个平滑曲线图,会更加赏心悦目,这就好比现在的手机app移动客户端上,从最初的四方四正到现在的平滑圆角 ...

  6. Vue整合Cesium的博文

    参考链接: 1.Vue 集成 Cesium 2.vue/cli3引入cesium 3.Vue2+Cesium.js展示地图 4.vue-cli3 引入 cesium 5.Vue Cli 4 引入 Ce ...

  7. IM全文检索技术专题(四):微信iOS端的最新全文检索技术优化实践

    本文由微信开发团队工程师" qiuwenchen"分享,原题"iOS微信全文搜索技术优化",有修订. 1.引言 全文搜索是使用倒排索引进行搜索的一种搜索方式.倒 ...

  8. dotnet最小webApi开发实践

    dotnet最小webApi开发实践 软件开发过程中,经常需要写一些功能验证代码.通常是创建一个console程序来验证测试,但黑呼呼的方脑袋界面,实在是不讨人喜欢. Web开发目前已是网络世界中的主 ...

  9. 手把手带你使用Karpenter减少K8s集群资源浪费

    Kubernetes 集群的主要成本因素之一是数据平面上的计算层.将 Kubernetes 集群运行在 Amazon EC2 Spot 实例上是一种显著降低计算成本的有效方式.使用 Spot 实例可以 ...

  10. webpack使用详解

    官网 官网:https://webpack.js.org 中文网:https://www.webpackjs.com 一.介绍 从webpack4.+进行介绍,会对Webpack常用配置一一讲解,各个 ...