其实最优的方法其他的题解已经讲得很好了,本题解仅用于记录和分享一个新的思路。


这道题是让你输出符合条件的序列,而序列的每个数之间具有一定的逻辑关系,很容易想到拓扑排序,于是此题就变为,如何找出满足条件的逻辑关系。

我们可以先看一下操作次数最多的序列:

(每一条红线都是一次操作),我们可以删除一次操作,当且仅当左半边与右半边都排好序的情况下,即删除了所有子操作的情况下,使得左半边与右半边中间建一条边,如图:

我们可以通过在\(1\)与\(2\)之间建一条边来删除\(1\)与\(2\)两者的操作

我们还可以通过在\(2\)与\(3\)之间建一条边来删除\(1\)与\(2\)之间,\(3\)与\(4\)之间的操作,但此时\(1\)与\(2\),\(3\)与\(4\)之间必须已经建边

上述操作可以通过递归完成,最后再跑一边拓扑排序,复杂度\(O(nlogn)\)

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
int n,k;
struct Edge
{
int to,nxt;
}e[100005];
int fir[100005],size;
int d[100005];
void add(int u,int v)
{
e[++size].to=v;
e[size].nxt=fir[u];
fir[u]=size;
++d[v];
}
int cnt;
void merge(int l,int r)
{
if(l==r-1)
{
return ;
}
int mid=(l+r)/2;
merge(l,mid);
merge(mid,r);
if(cnt>k)
{
add(mid-1,mid);
cnt-=2;
}
}
queue <int> q;
int ans[100005];
void top()
{
for(int i=n-1;i>=0;--i)
{
if(d[i]==0)
q.push(i);
}//一定要反向塞入,拓扑排序仅能保证逻辑关系,本题顺序非正即反,所以未建边的位置就是反的
cnt=0;
while(q.size())
{
int tmp=q.front();
q.pop();
ans[tmp+1]=++cnt;//我们建边和拓扑的是点的位置,根据出队顺序决定数字顺序
for(int i=fir[tmp];i;i=e[i].nxt)
{
--d[e[i].to];
if(d[e[i].to]==0)
q.push(e[i].to);
}
}
}
int main()
{
cin>>n>>k;
if(k%2==0||k>2*n-1)
{
printf("-1\n");
return 0;
}
cnt=2*n-1;
merge(0,n);
top();
for(int i=1;i<=n;++i)
{
printf("%d ",ans[i]);
}
printf("\n");
return 0;
}

CF873D Merge Sort的更多相关文章

  1. [算法]——归并排序(Merge Sort)

    归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...

  2. SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join

    nested loops join(嵌套循环)   驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...

  3. 归并排序(Merge Sort)

    归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序 ...

  4. 归并排序(merge sort)

    M erge sort is based on the divide-and-conquer paradigm. Its worst-case running time has a lower ord ...

  5. Summary: Merge Sort of Array && 求逆序对

    常用算法(后面有inplace版本): package ArrayMergeSort; import java.util.Arrays; public class Solution { public ...

  6. 基础排序算法之并归排序(Merge Sort)

    并归排序是学习分治法 (Merge Sort) 的好例子.而且它相对于选择,插入,冒泡排序来说,算法性能有一定提升.我首先会描述要解决的问题,并给出一个并归排序的例子.之后是算法的思路以及给出伪代码. ...

  7. Divide and Conquer.(Merge Sort) by sixleaves

    algo-C1-Introductionhtml, body {overflow-x: initial !important;}html { font-size: 14px; }body { marg ...

  8. STL 源代码剖析 算法 stl_algo.h -- merge sort

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...

  9. Sort list by merge sort

    使用归并排序对链表进行排序 O(nlgn) 的时间效率 /** * Definition for singly-linked list. * struct ListNode { * int val; ...

随机推荐

  1. uboot分析——预备知识

    1. 刷机 刷机是使用fastboot,所以板子首先要已经能运行uboot,若ROM没有uboot,则使用sd卡或usb启动uboot. 板子进入uboot后,输入fastboot命令,进入fastb ...

  2. SSH2中的笔记

    1.web后端实质就是对表的添.删.查.改: 第一步:对系统进行分析,然后构思. 第二步:画出E-R图,设计出表或写出相应的实体类. 第三步:按照最简单的思想去设计的话,一个action-->一 ...

  3. linux常用配置文件和命令总结

    常用配置文件说明: 1..设置-n永远生效:Vim的配置文件:命令模式想永久生效, ~/.vimrc,新建文件,在里面输入保存即可 2.设置别名永远生效:在~/.bashrc  修改当前用户家目录里的 ...

  4. pycharm远程编译

    1. 按照 https://www.cnblogs.com/xiongmao-cpp/p/7856596.html 完成配置 2. 使用步骤: (1)在本地新建代码文件或工程 (2)编写代码,完成后若 ...

  5. Python_爬虫_百度图片

    百度图片有些有编码问题,暂时不能爬取,多试几个 #思路:抓取图片地址,根据地址转存图片(注意名称):难点:转码 # -*- coding:utf-8 -*- from urllib import re ...

  6. 「NOIP2016」天天爱跑步 题解

    (声明:图片来源于网络) 「NOIP2016」天天爱跑步 题解 题目TP门 题目 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...

  7. 【进阶之路】Mybatis-Plus中乐观锁@version注解的问题与解决方案

    大家好,我是练习java两年半时间的南橘,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西.知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了 ...

  8. Nginx 解析漏洞复现

    一.漏洞描述 该漏洞与nginx.php版本无关,属于用户配置不当造成的解析漏洞 二.漏洞原理 1.由于nginx.conf的如下配置导致nginx把以'.php'结尾的文件交给fastcgi处理,为 ...

  9. 运维自动化之1 - ansible 批量主机管理

    2000 - 2016 年,维护的小型机.linux刚开始的2台增加到上千台,手工检查.日常版本升级需要管理太多设备,必须通过运维自动化实现 特别是版本升级,需要到同类机器部署代码.起停设备,必须在一 ...

  10. __FUNCTION__