【BZOJ4278】[ONTAK2015]Tasowanie 后缀数组

【BZOJ4278】[ONTAK2015]Tasowanie

Description

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

Input

第一行包含一个正整数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)。

Output

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

Sample Input

6

1 2 3 1 2 4

7

1 2 2 1 3 4 3

Sample Output

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

题解:后缀数组无脑码,将两个串连成一个,中间用极大值隔开,然后跑后缀数组,每次取两个串开头的比较排名就可以了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=400010;
int N,M,n,m,maxx;
int r[maxn],ra[maxn],rb[maxn],sa[maxn],st[maxn],rank[maxn];
void work()
{
    int i,j,p,*x=ra,*y=rb;
    for(i=0;i<n;i++)    st[x[i]=r[i]]++;
    for(i=1;i<m;i++)    st[i]+=st[i-1];
    for(i=n-1;i>=0;i--)    sa[--st[x[i]]]=i;
    for(j=p=1;p<n;j<<=1,m=p)
    {
        for(i=n-j,p=0;i<n;i++)    y[p++]=i;
        for(i=0;i<n;i++)    if(sa[i]>=j)    y[p++]=sa[i]-j;
        for(i=0;i<m;i++)    st[i]=0;
        for(i=0;i<n;i++)    st[x[y[i]]]++;
        for(i=1;i<m;i++)    st[i]+=st[i-1];
        for(i=n-1;i>=0;i--)    sa[--st[x[y[i]]]]=y[i];
        for(swap(x,y),i=p=1,x[sa[0]]=0;i<n;i++)
            x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
    }
    for(i=0;i<n;i++)    rank[sa[i]]=i;
}
int main()
{
    int i;
    scanf("%d",&N);
    for(i=0;i<N;i++)    scanf("%d",&r[i]),m=max(m,r[i]);
    scanf("%d",&M);
    for(i=0;i<M;i++)    scanf("%d",&r[N+i+1]),m=max(m,r[N+i+1]);
    r[N]=m+1,n=N+M+2,m+=2;
    work();
    int a=0,b=N+1;
    for(i=0;i<N+M;i++)
    {
        if(rank[a]>rank[b]&&b<N+M+1)
            printf("%d ",r[b++]);
        else
            printf("%d ",r[a++]);
    }
    printf("\n");
    return 0;
}
时间: 2024-10-03 14:41:59

【BZOJ4278】[ONTAK2015]Tasowanie 后缀数组的相关文章

【BZOJ-4278】Tasowanie 后缀数组 + 归并

4278: [ONTAK2015]Tasowanie Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 164  Solved: 80[Submit][Status][Discuss] Description 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. Input 第一行包含一个正整数n(1<=n<=200000),表示A串的长度. 第二行包含n个正整数,其中第i个数表示A[i](1<=A[i]

bzoj4278: [ONTAK2015]Tasowanie

stl::sort实现的后缀数组,超级慢. 变量名打错好几个导致WA好几次. http://www.lydsy.com/JudgeOnline/problem.php?id=4278 /************************************************************** Problem: 4278 User: 1349367067 Language: C++ Result: Accepted Time:7900 ms Memory:13776 kb ***

SPOJ 705 Distinct Substrings(后缀数组)

[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每个后缀对答案的贡献为n-sa[i]+1-h[i], 因为排名相邻的后缀一定是公共前缀最长的, 那么就可以有效地通过LCP去除重复计算的子串. [代码] #include <cstdio> #include <cstring> #include <algorithm> usi

hdu5769--Substring(后缀数组)

题意:求含有某个字母的某个字符串的不同子串的个数 题解:后缀数组,记录每个位置距离需要出现的字母的距离就可以了.因为不太了解后缀模版卡了一会,还是很简单的. 记住sa和height数组都是1-n的下标. //后缀数组 #include <stdio.h> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll;

hdu 3518 Boring counting 后缀数组LCP

题目链接 题意:给定长度为n(n <= 1000)的只含小写字母的字符串,问字符串子串不重叠出现最少两次的不同子串个数; input: aaaa ababcabb aaaaaa # output 2 3 3 思路:套用后缀数组求解出sa数组和height数组,之后枚举后缀的公共前缀长度i,由于不能重叠,所以计数的是相邻height不满足LCP >= i的. 写写对后缀数组倍增算法的理解: 1.如果要sa数组对应的值也是1~n就需要在最后加上一个最小的且不出现的字符'#',里面y[]是利用sa数

【tyvj1860】后缀数组

描述 我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串.后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0你的任务就是求出SA和height这两个数组.字符串长度<=200000 输入格式 一行,为描述中的字符串(仅会出现小写

BZOJ 3238 AHOI 2013 差异 后缀数组+单调栈

题目大意: 思路:一看各种后缀那就是后缀数组没跑了. 求出sa,height之后就可以乱搞了.对于height数组中的一个值,height[i]来说,这个值能够作为lcp值的作用域只在左边第一个比他小的位置到右边第一个比他小的位置.这个东西很明显可以倍增RMQ+二分/单调栈. 之后就是数学题了 Σlen[Ti] + len[Tj] = (len + 1) * len * (len - 1),之后吧所有求出来的Σ2 * lcp(Ti,Tj)减掉就是答案. 记得答案开long long CODE:

hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分)

Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 288    Accepted Submission(s): 108 Problem Description Long long ago, there lived a lot of rabbits in the forest. One day, the

hdu 4416 Good Article Good sentence(后缀数组&amp;思维)

Good Article Good sentence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2308    Accepted Submission(s): 649 Problem Description In middle school, teachers used to encourage us to pick up pre