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


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

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

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

我们可以通过在\(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. DB2中SQL基本语句的操作

    完全转载自:http://blog.sina.com.cn/s/blog_67aaf4440100v01p.html --创建数据库 create database Etp; --连接数据库 conn ...

  2. ASP.NET Core管道详解[2]: HttpContext本质论

    ASP.NET Core请求处理管道由一个服务器和一组有序排列的中间件构成,所有中间件针对请求的处理都在通过HttpContext对象表示的上下文中进行.由于应用程序总是利用服务器来完成对请求的接收和 ...

  3. javascript实现文件上传之前的预览功能

    1.首先要给上传文件表单控件和图片控件设置name属性 <div class="form-group">                    <label fo ...

  4. 阿里面试官:小伙子,你给我说一下JVM对象创建与内存分配机制吧

    内存分配机制   逐步分析 类加载检查: 虚拟机遇到一条new指令(new关键字.对象的克隆.对象的序列化等)时,会先去检查这个指令的参数在常量池中定位到一个类的符号引用,并且这个符号引用代表的类是否 ...

  5. 怎么在苹果笔记本上用Folx重新下载已完成的任务

    大家在完成了任务下载后,有时会将下载的文件移动到其他文件夹中,或者是,当下载的文件已经使用完毕时,有些用户会将文件删除.以上的两种情况,都会导致Folx所属任务查看功能失效,也就是说,无法找到任务对应 ...

  6. 苹果电脑清理软件CleanMyMac X好用吗?

    为了维护mac系统健康,优化系统功能,我们需要定期给电脑进行清理.那么作为mac清理软件CleanMyMac X软件具备哪些独特性和实用性呢?今天就给大家说明一下. 1. 简洁大气的外观. 用户正版官 ...

  7. 追踪聚光特效怎么实现,有Vegas就够了

    舞台聚光灯大家一定都不陌生,在电视上某些颁奖活动里,主持人的进场一定伴随着舞台灯光的聚光效果.随着主持人的移动,灯光也随之移动.这里的舞台灯光就起到了一个追踪聚光的效果. Vegas Pro 16 增 ...

  8. 带你了解Boom 3D的Mac版音效模式

    音乐是很好的情绪抒发途径,因为音乐蕴含了很多信息,包含了很多情感,所以我们聆听不同种类的音乐的时候会产生不同的心理感受.这就是音乐的魅力,可以让人产生共鸣引发无数的思绪.为了能够更好的体会感受音乐可以 ...

  9. css3系列之transform 详解skew

    skew skewx skewy skewX()  倾斜该元素,里面填的是角度,下面↓ 你会看到,随着元素被倾斜,高度居然不变.聪明的你,一定会知道,高度不变,代表了,Y轴被拉伸了. 跟scale 同 ...

  10. web自动化测试,弹出窗的操作

    弹出窗有两种: 1.alert弹窗 2.页面弹出窗 什么是alert弹窗呢,点击某一个事件后,会弹出一个弹窗,如下图所示,相信大家在测试中有遇到过,怎么操作它呢 1.1弹窗出现后,使用switch_t ...