传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=4278
题目大意
给定两个数字串A和B,要求归并得到一个字典序最小的数字串T
题解
每次选取后缀最小的输出
用二分+HASH求出lcp后判断后缀大小
const
maxn=200005;
seed=131;
mmod=1073741823;
var
x:array[1..2,0..maxn]of int64;
y,z:array[0..maxn]of longint;
pow:array[0..maxn]of int64;
i,j,k:longint;
n,m,tt:longint;
function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
function hash(kin,l,r:longint):int64;
begin
exit((x[kin,r]-x[kin,l-1]*pow[r-l+1] mod mmod+mmod)mod mmod);
end;
function query(a,b:longint):longint;
var l,r,mid,tt:longint;
begin
l:=1; r:=min(n-a+1,m-b+1); tt:=0;
while l<=r do
begin
mid:=(l+r)>>1;
if hash(1,a,a+mid-1)=hash(2,b,b+mid-1)
then begin tt:=mid; l:=mid+1; end
else r:=mid-1;
end;
exit(tt);
end;
begin
readln(n); x[1,0]:=0;
for i:=1 to n+1 do
begin
if i=n+1
then x[1,i]:=2000
else read(x[1,i]);
y[i]:=x[1,i];
x[1,i]:=(x[1,i-1]*seed+x[1,i])mod mmod;
end;
readln(m); x[2,0]:=0;
for i:=1 to m+1 do
begin
if i=m+1
then x[2,i]:=2000
else read(x[2,i]);
z[i]:=x[2,i];
x[2,i]:=(x[2,i-1]*seed+x[2,i])mod mmod;
end;
pow[0]:=1;
for i:=1 to max(n,m) do
pow[i]:=(pow[i-1]*seed)mod mmod;
i:=1; j:=1;
while (i<=n)and(j<=m) do
begin
tt:=query(i,j);
if y[i+tt]<z[j+tt]
then begin write(y[i],' '); inc(i); end
else begin write(z[j],' '); inc(j); end;
end;
for k:=i to n do
write(y[k],' ');
for k:=j to m do
write(z[k],' ');
writeln;
end.