题目链接

最近做题目好像有点东一榔头西一棒。好吧其实订正模拟题的时候需要用到什么感觉不太熟的就写一下吧。

显然直接贪心,比较两个点后面的串的字典序,小就选谁就可以了。

可以把两个串接起来,加一个\(inf\)分隔。然后用\(SA\)的\(rank\)数组就可以比较大小了。

也可以用哈希+二分比较。

#include<bits/stdc++.h>
using namespace std;
#define fec(i,x,y) (int i=head[x],y=g[i].to;i;i=g[i].ne,y=g[i].to)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define isin(x,S) (((S)>>((x)-1))&1)
#define fi first
#define se second
#define pb push_back
template<typename I>inline void read(I&x){int f=0,c;while(!isdigit(c=getchar()))c=='-'?f=1:0;x=c&15;while(isdigit(c=getchar()))x=(x<<1)+(x<<3)+(c&15);f?x=-x:0;}
template<typename A,typename B>inline char SMAX(A&a,const B&b){return a<b?a=b,1:0;}
template<typename A,typename B>inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}
typedef long long ll;typedef unsigned long long ull;typedef pair<int,int>pii; const int N=400000+7;
int n,m,a[N],b[N],ans[N]; int sa[N],rk[N],sec[N],tax[N];
inline void MakeSA(){
int n=::n+::m+1,m=1001,*rnk=rk,*sc=sec;
for(int i=1;i<=m;++i)tax[i]=0;
for(int i=1;i<=n;++i)tax[rnk[i]=a[i]]++;
for(int i=1;i<=m;++i)tax[i]+=tax[i-1];
for(int i=n;i;--i)sa[tax[rnk[i]]--]=i;
for(int k=1;k<=n;k<<=1){
int p=0;
for(int i=n-k+1;i<=n;++i)sc[++p]=i;
for(int i=1;i<=n;++i)if(sa[i]>k)sc[++p]=sa[i]-k;
for(int i=1;i<=m;++i)tax[i]=0;
for(int i=1;i<=n;++i)tax[rnk[sc[i]]]++;
for(int i=1;i<=m;++i)tax[i]+=tax[i-1];
for(int i=n;i;--i)sa[tax[rnk[sc[i]]]--]=sc[i];
swap(rnk,sc);p=rnk[sa[1]]=1;
for(int i=2;i<=n;++i)rnk[sa[i]]=(sc[sa[i]]==sc[sa[i-1]]&&sc[sa[i]+k]==sc[sa[i-1]+k]?p:++p);
if(p>=n)break;else m=p;
}
for(int i=1;i<=n;++i)rk[sa[i]]=i;
} int main(){
#ifdef hzhkk
freopen("hkk.in","r",stdin);
#endif
read(n);for(int i=1;i<=n;++i)read(a[i]);
a[n+1]=1001;
read(m);for(int i=1;i<=m;++i)read(b[i]),a[i+n+1]=b[i];
MakeSA();
for(int i=1,j=1,k=1;i<=n||j<=m;++k){
if(j>m||(i<=n&&rk[i]<rk[j+n+1]))ans[k]=a[i++];
else ans[k]=b[j++];
}
for(int i=1;i<=n+m;++i)printf("%d%c",ans[i]," \n"[i==n+m]);
}

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

  1. 【bzoj4278】[ONTAK2015]Tasowanie 贪心+后缀数组

    题目描述 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. 输入 第一行包含一个正整数n(1<=n<=200000),表示A串的长度. 第二行包含 ...

  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. socket函数库简单封装

    #pragma once #ifndef WINSOCK_H #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib" ...

  2. 5 October

    POJ2676 Sudoku 位运算 + 搜索.更好的优化方法:方案数最小的空格先填. 把某一位 置为 0:a &=~ (1<<n) 把某一位 置为 1:a |= (1<&l ...

  3. .Net服务组件(ServicedComponent)简介及其使用

    .NET Enterprise Services 为企业应用程序提供重要的基础结构.COM+ 为企业环境中部署的组件编程模型提供服务结构.System.EnterpriseServices命名空间向 ...

  4. 基于canvas实现的高性能、跨平台的股票图表库--clchart

    什么是 ClChart? ClChart是一个基于canvas创建的简单.高性能和跨平台的股票数据可视化开源项目.支持PC.webApp以及React Native和Weex等平台.在React Na ...

  5. mypwd实现

    实现mypwd 要求 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 步骤 查看pwd的作用man -k pwd ...

  6. jsc2019_qualE Card Collector

    题目大意 给你n个点的坐标和权值 问先在每一行选一个点再在每一列选一个没选过的点 求最大权值和 分析 可以想到将点转化为边,将两个坐标对应两个点 所以问题转化为选H+W个边 使得所有边的度都不为0 则 ...

  7. leetcode 155. 最小栈(c++)

    设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) -- 将元素 x 推入栈中.pop() -- 删除栈顶的元素.top() -- 获取栈顶元素.get ...

  8. centos7安装MongoDB4.0(yum安装)

    1.添加 yum repo vi /etc/yum.repos.d/mongodb-org-4.0.repo 添加如下内容 [mongodb-org-4.0] name=MongoDB Reposit ...

  9. 第 3 章 前端基础之JavaScript

    一.JavaScript概述 1.javascripts的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中),后将其改名ScriptE ...

  10. ab工具进行压力测试

    简介与安装 ab:Apache Benchmark,只要我们安装了Apache,就能够在Apache的安装目录中找到它. yum | apt 安装的Apache  ab的目录一般为/usr/bin 也 ...