第十一次新生排位赛

来源:互联网 发布:pic下载软件 编辑:程序博客网 时间:2024/05/16 05:51

第一题

目前还没做出来,竟然是离线打好表,然后把数据复制到代码的数组里

 

第二题

跟上次一样是后缀数组

时间限制 10000 ms 内存限制 65536 KB

题目描述

田田被老师要求背诵一个字符串,田田刚刚背了一个子串,说他记性差他还不承认,背下这个子串后却忘了这个子串是从哪里开始的。
现在田田把这个字符串给你,并且让你告诉他至少一次背多长的子串才不可能产生歧义,即不存在另一个子串与它相等

输入格式

输入仅一行,即要求田田背诵的字符串
长度<=10^6

输出格式

输出一行,即不产生歧义串的最小串长

输入样例

abcdabcd

输出样例

5
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
 
#define maxn 1000007
usingnamespace std;
 
int n, k;
int r[maxn];
int tmp[maxn];
int lcp[maxn];
int sa[maxn];
string s;
boolcompare_sa(inti, int j)
{
    if(r[i]!=r[j]) returnr[i]<r[j];
    else
    {
        intri = i+k<=n?r[i+k]:0;
        intrj = j+k<=n?r[j+k]:0;
        returnri<rj;
    }
}
voidconstruct_sa()
{
    for(int i=0; i<=n; i++)
    {
        sa[i]=i;
        r[i] = s[i];
    }
    inttot;
    for(k=1; k<=n ;k<<=1)
    {
        sort(sa, sa+n+1, compare_sa);
 
        tot = 0;
        tmp[sa[0]] = 0;
        for(int i=1; i<=n; i++)
        {
            if(compare_sa(sa[i-1], sa[i])) tmp[sa[i]] = ++tot;
            elsetmp[sa[i]] = tot;
        }
        for(int i=0; i<=n; i++)
            r[i] = tmp[i];
 
        if(tot>=n) break;
    }
 
 
}
voidconstruct_lcp()
{
    for(int i=0; i<=n; i++)
    {
        r[sa[i]] = i;
    }
    inth = 0;
    lcp[0] = 0;
    for(int i=0; i<n; i++)
    {
        if(h>0)
            lcp[i] = --h;
        else
        {
            intj=sa[r[i]-1];
            for(h=0; j+h<n&&i+h<n; h++)
                if(s[j+h] != s[i+h])
                    break;
            lcp[i] = h;
        }
 
    }
}
 
int main()
{
    cin >> s;
    n=s.length();
    //printf("%d\n", s[n]);
    construct_sa();
    construct_lcp();
    intans = 0;
    for(int i=0; i<n; i++)
        ans = max(ans, lcp[i]);
    printf("%d\n", ans+1);
    return0;
}

第三题

0 0
原创粉丝点击