码迷,mamicode.com
首页 > 其他好文 > 详细

8.30 广泛交换意见

时间:2019-08-30 23:24:04      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:集合   下标   转化   去掉   等价   pos   一个   字典   line   

题意

给一个长度为\(N\)的排列\(P\)与一个正整数\(K\),可以进行如下操作:

对于两个满足\(|i-j|\geq K\)\(|P_i-P_j|=1\)的下标\(i\)\(j\),交换\(P_i\)\(P_j\)

我们的目的是要求操作后的排列字典序最小


解法

首先,这两个条件都不好判断,直接做是不太好搞的

考虑把这个数组映射一下(这好像是对于排列的一个常见套路?)

\(pos[P_i]=i\),即元素\(P_i\)的位置为\(i\)

我们对\(pos\)数组进行操作,操作就转化为了:

可以交换两个相邻元素,并且相邻元素的差的绝对值\(\geq K\)

我们可以发现,如果我们要求\(P\)的字典序最小,实际上与要求\(pos\)的字典序最小是等价的,因为\(\lfloor\)靠前的权值尽量小\(\rceil\)\(\lfloor\)权值较小的尽量靠前\(\rceil\)这两个要求是等价的

我们发现,对于两个元素\(i,j,i<j\),如果\(|i-j|<K\),那么它们的相对位置永远不会改变

也就是说无论进行多少次交换,如何交换,\(i\)一定会在\(j\)之前

这就启发我们用拓扑排序进行求解,在多种拓扑序方案中选择字典序最小的一个即可,这里用优先队列实现

那么接下来的任务就是建图了

为了避免重复连边,我们规定一个元素仅能向其后面的元素连边

考虑连边的意义,若存在一条有向边\(E(u,v)\),说明\(u,v\)之间的相对顺序已经确定即\(v\)\(u\)之后

对于一个元素\(x\),它会向值域为\((x-K,x)\cup (x,x+K)\)的元素连边,并且要求这些元素的初始位置在\(x\)之后

但是这样暴力连边,边的数量是\(O(N^2)\)级别的

我们可以发现,相对顺序是有传递关系的,比如说对于三条边\(A \rightarrow B, B\rightarrow C,A\rightarrow C\),第三条边完全可以被前两条边替代,那么它就是无效的

为了去掉这些无效的边,我们规定\(x\)只向值域为\((x-K,x)\)\((x,x+K)\)中的位置在\(x\)之后且最小的元素连边

这是因为我们可以发现由于这两个集合的大小均不超过\(K\),那么它们内部一定是互有连边的

那么我们只需要连一个位置最靠前的元素,就可以根据这个元素扩张到整个集合了

找到这个元素可以用线段树实现


代码

还没码。。

8.30 广泛交换意见

标签:集合   下标   转化   去掉   等价   pos   一个   字典   line   

原文地址:https://www.cnblogs.com/VeniVidiVici/p/11437438.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!