题目描述

给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T。

输入

第一行包含一个正整数n(1<=n<=200000),表示A串的长度。
第二行包含n个正整数,其中第i个数表示A[i](1<=A[i]<=1000)。
第三行包含一个正整数m(1<=m<=200000),表示B串的长度。
第四行包含m个正整数,其中第i个数表示B[i](1<=B[i]<=1000)。

输出

输出一行,包含n+m个正整数,即字典序最小的T串。

样例输入

6
1 2 3 1 2 4
7
1 2 2 1 3 4 3

样例输出

1 1 2 2 1 2 3 1 2 3 4 3 4


题解

贪心+后缀数组

贪心法则:选择字典序小的串。

那么我们就可以将两个串放到一起,利用后缀数组求排名,减少时间。

需要注意的是两个串之间需要加一个最大数,因为如果第一个串全部用完,rank应该为最大。

#include <cstdio>
#define N 400005
int ws[N] , wv[N] , wa[N] , wb[N] , sa[N] , r[N] , rank[N] , m = 1003 , n , a[N];
void da()
{
int i , j , p , *x = wa , *y = wb , *t;
for(i = 0 ; i < m ; i ++ ) ws[i] = 0;
for(i = 0 ; i < n ; i ++ ) ws[x[i] = r[i]] ++ ;
for(i = 1 ; i < m ; i ++ ) ws[i] += ws[i - 1];
for(i = n - 1 ; i >= 0 ; i -- ) sa[--ws[x[i]]] = i;
for(p = j = 1 ; p < n ; j <<= 1 , m = p)
{
for(p = 0 , i = n - j ; i < n ; i ++ ) y[p ++ ] = i;
for(i = 0 ; i < n ; i ++ ) if(sa[i] - j >= 0) y[p ++ ] = sa[i] - j;
for(i = 0 ; i < n ; i ++ ) wv[i] = x[y[i]];
for(i = 0 ; i < m ; i ++ ) ws[i] = 0;
for(i = 0 ; i < n ; i ++ ) ws[wv[i]] ++ ;
for(i = 1 ; i < m ; i ++ ) ws[i] += ws[i - 1];
for(i = n - 1 ; i >= 0 ; i -- ) sa[--ws[wv[i]]] = y[i];
for(t = x , x = y , y = t , x[sa[0]] = 0 , p = i = 1 ; i < n ; i ++ )
{
if(y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j])
x[sa[i]] = p - 1;
else
x[sa[i]] = p ++ ;
}
}
for(i = 1 ; i < n ; i ++ )
rank[sa[i]] = i;
}
int main()
{
int n1 , n2 , i , p1 , p2;
scanf("%d" , &n1);
for(i = 0 ; i < n1 ; i ++ )
{
scanf("%d" , &a[i]);
r[i] = a[i];
}
scanf("%d" , &n2);
for(i = n1 + 1 ; i < n1 + n2 + 1 ; i ++ )
{
scanf("%d" , &a[i]);
r[i] = a[i];
}
r[n1] = 1001;
r[n1 + n2 + 1] = 0;
n = n1 + n2 + 2;
da();
p1 = 0;
p2 = n1 + 1;
while(p1 < n1 || p2 < n1 + n2 + 1)
{
if(p2 < n1 + n2 + 1 && rank[p2] < rank[p1])
printf("%d " , a[p2 ++ ]);
else
printf("%d " , a[p1 ++ ]);
}
printf("\n");
return 0;
}

【bzoj4278】[ONTAK2015]Tasowanie 贪心+后缀数组的更多相关文章

  1. [BZOJ4278] [ONTAK2015]Tasowanie 贪心+后缀数组

    题目链接 最近做题目好像有点东一榔头西一棒.好吧其实订正模拟题的时候需要用到什么感觉不太熟的就写一下吧. 显然直接贪心,比较两个点后面的串的字典序,小就选谁就可以了. 可以把两个串接起来,加一个\(i ...

  2. 【bzoj1692】[Usaco2007 Dec]队列变换 贪心+后缀数组

    题目描述 FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”.在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过. ...

  3. [bzoj1692][Usaco2007 Dec]队列变换——贪心+后缀数组

    Brief Description 给定一个数列,您每次可以把数列的最前面的数或最后面的数移动到新数列的开头,使得新数列字典序最小.输出这个新序列. Algorithm Design 首先我们可以使用 ...

  4. POJ3617:Best Cow Line (贪心&&后缀数组)

    FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competiti ...

  5. BZOJ4278 [ONTAK2015]Tasowanie[后缀数组+贪心]

    题目 求两数组归并后的数组最小字典序排列. 嘛,可能本人在贪心这块还是太弱了(或者说什么都弱),如果不知道是字符串题估计也想不起来用sa. 显然看得出归并时字典序小的那个数组先往里面加,这就是要比较两 ...

  6. bzoj4278[ONTAK2015]Tasowanie & bzoj1692[USACO 2007Dec]队列变换(Best Cow Line) 贪心正确性证明

    做法网上到处都有就不说了. 这题其实是之前做的….不过由于人太傻现在才想明白比较字典序进行贪心的正确性…. 方便起见,在两个串的最右端都加上很大但不相同的字符,避免第lcp+1个字符不存在的边界. 如 ...

  7. BZOJ4278 : [ONTAK2015]Tasowanie

    首先在串的末尾加上1000,然后进行归并,每次取字典序较小的那个后缀即可. 用hash+二分支持查询lcp,时间复杂度$O(n\log n)$. #include<cstdio> type ...

  8. 1692. [USACO07DEC] 队列变换【后缀数组+贪心】

    Description FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”.在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席 ...

  9. [bzoj4278][ONTAK2015]Tasowanie_后缀数组_贪心

    Tasowanie bzoj-4278 ONTAK-2015 题目大意:给定两个字符串,求两个字符串二路归并之后生成的字典序最小的字符串是什么. 注释:$1\le len_1,len_2\le 2\c ...

随机推荐

  1. CDH集群搭建视频教程 百度云网盘下载

     CDH集群搭建视频教程 百度云网盘下载 链接: http://pan.baidu.com/s/1i5DVBlb   密码:2mny

  2. 从Github开源项目《云阅》所学到的知识

    感谢开源,感谢大神,才让我们这些菜鸟成长! 附上云阅开源项目地址:点我吧. 1.轮播图的实现. 现在的APP基本都会实现这个功能吧,然后一直都找不到好的第三方库,能够满足各种需求.然而碰到了这个开源库 ...

  3. EL/JSTL-jsp页面更简单的输出方式

    1.EL(Expression Language):表达式语言,用于页面输出 格式:${表达式} EL支持四则运算,关系运算[常用eq来比较字符串或判断相等],逻辑运算 EL访问空间内对象,[类.对象 ...

  4. 北京Uber优步司机奖励政策(1月2日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. python 安装 MySQL-python

    $python >>> import MySQLdb Traceback (most recent call last): File "<stdin>" ...

  6. MySQL 取得字段子串修改

    MySQL 中, GeneID 为 GRMZM2G549533_P01,1123,45 , 需要修改为 GRMZM2G549533_P01 update test set GeneID=SUBSTRI ...

  7. Ubuntu16.04比较好的一系列软件安装介绍

    https://blog.csdn.net/Gerald_Jones/article/details/80784976

  8. hdu2147kiki's game(找规律)

    kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 40000/10000 K (Java/Others)Total ...

  9. 【SpringCloud】第五篇: 路由网关(zuul)

    前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...

  10. 《Git学习指南》学习笔记(二)

    第三章 提交究竟是什么 每次提交都会生成一个40位的散列值.只要知道散列值,我们就可以恢复到该次提交,这个操作也被称之为检出(checkout)操作. 访问权限与时间戳 Git会保存每个文件原有的访问 ...