解:考场上爆0了......

回想怎么求两个排列的最长公共子序列。

回想怎么求1~n每个数恰出现两次的两个序列的最长公共子序列。就是每个数替换为它在另一个序列里的出现位置,降序。

所以我们可以把这每个空位都倒序填入m个数,然后暴力,最后输出方案。

考虑优化。发现在每个空位的时候,这m个数都是单降的。直接拿指针在单调栈上扫,可以O(top + m)转移。

关于记录方案,每个位置记录以它结尾的lis中的前一个非-1位置,以及在这之间有多少个-1。

然后就可以把空间优化到O(n)。

  1. #include <bits/stdc++.h>
  2.  
  3. typedef long long LL;
  4. const int N = ;
  5. const LL INF = 0x3f3f3f3f3f3f3f3fll;;
  6.  
  7. struct Node {
  8. int a, b;
  9. Node(int A = , int B = ) {
  10. a = A;
  11. b = B;
  12. }
  13. }frp[N], fr[N];
  14.  
  15. LL a[N], b[N], p[N];
  16. int top, n, m;
  17. bool vis[N];
  18.  
  19. int main() {
  20. scanf("%d", &n);
  21. for(int i = ; i <= n; i++) {
  22. scanf("%lld", &a[i]);
  23. }
  24. scanf("%d", &m);
  25. for(int i = ; i <= m; i++) {
  26. scanf("%lld", &b[i]);
  27. }
  28. std::sort(b + , b + m + );
  29. std::reverse(b + , b + m + );
  30. a[n + ] = INF;
  31. for(int i = ; i <= n + ; i++) {
  32. if(a[i] != -) {
  33. int l = , r = top;
  34. while(l < r) {
  35. int mid = (l + r + ) >> ;
  36. if(p[mid] < a[i]) l = mid;
  37. else r = mid - ;
  38. }
  39. fr[i] = frp[r];
  40. if(r == top) {
  41. p[++top] = a[i];
  42. frp[top] = Node(i, );
  43. }
  44. else if(p[r + ] > a[i]) {
  45. p[r + ] = a[i];
  46. frp[r + ] = Node(i, );
  47. }
  48. }
  49. else {
  50. int p1 = top;
  51. for(int j = ; j <= m; j++) {
  52. while(p1 && p[p1] >= b[j]) {
  53. p1--;
  54. }
  55. Node temp = frp[p1];
  56. temp.b++;
  57. if(p1 == top) {
  58. p[++top] = b[j];
  59. frp[top] = temp;
  60. }
  61. else if(p[p1 + ] > b[j]) {
  62. p[p1 + ] = b[j];
  63. frp[p1 + ] = temp;
  64. }
  65. }
  66. }
  67. }
  68.  
  69. int now = frp[top].a, p1 = n, p2 = ;
  70. while(now) {
  71. if(fr[now].b) {
  72. while(p1 > now) p1--;
  73. while(b[p2] >= a[now]) p2++;
  74. for(int i = ; i <= fr[now].b; i++) {
  75. while(a[p1] != -) p1--;
  76. a[p1] = b[p2];
  77. vis[p2] = ;
  78. p2++;
  79. }
  80. }
  81. now = fr[now].a;
  82. }
  83.  
  84. p2 = ;
  85. for(int i = ; i <= n; i++) {
  86. if(a[i] == -) {
  87. while(vis[p2]) p2++;
  88. a[i] = b[p2];
  89. p2++;
  90. }
  91. }
  92.  
  93. for(int i = ; i <= n; i++) {
  94. printf("%lld ", a[i]);
  95. }
  96. return ;
  97. }

AC代码

小R的树(权限题)的更多相关文章

  1. 洛谷 U96762 小R与三角形 题解

    U96762 小R与三角形 原题链接 题目描述 小 R 所在的小镇有 n 个村落,这 n 个村落分布在一个圆周上,这些村落之间两两有直达的小路,小路可能相交,但不存在三条路交于一点.现在小 R 正好放 ...

  2. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  3. 【codevs2370】小机房的树 LCA 倍增

    2370 小机房的树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...

  4. Dynamic Rankings || 动态/静态区间第k小(主席树)

    JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...

  5. 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)

    点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...

  6. [poj2104]可持久化线段树入门题(主席树)

    解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序 ...

  7. POJ 3468 线段树裸题

    这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...

  8. HDU 2096 小明A+B --- 水题

    HDU 2096 /* HDU 2096 小明A+B --- 水题 */ #include <cstdio> int main() { #ifdef _LOCAL freopen(&quo ...

  9. 【BZOJ】【3280】小R的烦恼

    网络流/费用流 和软件开发那题基本相同,只是多加了一个“雇佣研究生”的限制:不同价格的研究生有不同的数量…… 那么只需加一个附加源点,对每一种研究生连边 S->ss 容量为l[i],费用为p[i ...

随机推荐

  1. C# Note23: 如何自定义类型使用foreach循环

    前言 在foreach语句代码中,我们经常是对List,Collection,Dictionary等类型的数据进行操作,不过C#允许用户自定义自己的类型来使用foreach语句.那么自定义类型能够使用 ...

  2. 剑指offer(7)

    今天的几道题目都是关于斐波那契数列的. 题目1: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 传统的方法采用递归函数,这种 ...

  3. 运维常用mysql语句

    1..select @@version; ##查询当前mysql的版本. 2. show variables like 'port';##查看mysql实例的端口. 3.show variables ...

  4. 关于WPF中Popup中的一些用法的总结

    Popup控件是一个常用的非常有用的控件,顾明思义就是弹出式控件,首先我们来看看MSDN对它的解释吧,表示具有内容的弹出窗口,这个是非常重要的控件,我们看看它的继承关系吧: System.Object ...

  5. 简单谈谈数据库DML、DDL和DCL的区别

    一.DML DML(data manipulation language)数据操纵语言: 就是我们最经常用到的 SELECT.UPDATE.INSERT.DELETE. 主要用来对数据库的数据进行一些 ...

  6. python数学第四天【古典概型】

  7. Span<T>

    Introduction Span<T> is a new type we are adding to the platform to represent contiguous regio ...

  8. Nginx 反向代理如何连接上游服务器

    L:92 想上游服务器先建立TCP连接 如三次握手 下面指令可以控制握手时间 proxy_next_upstream  指令当出现502可以换个上游服务器 Tcp keepalive 一般都是由进程在 ...

  9. 使用Promise解决多层异步调用的简单学习【转】

    前言 本文章转载文章: https://www.jianshu.com/p/29da9aef4c1c 第一次接触到Promise这个东西,是2012年微软发布Windows8操作系统后抱着作死好奇的心 ...

  10. Spring 使用介绍(八)—— 零配置(一)

    一.概述 所谓零配置,并不是说一点配置都没有了,而是配置很少而已.通过约定来减少需要配置的数量,提高开发效率. 零配置实现主要有以下两种方式: 惯例优先原则:也称为约定大于配置(convention ...