• LETTers练习赛第十场 第三题


    这题感觉 lcp 还是必须的,时限卡得比较紧,所以就只能扩展 kmp 了。但是比起后缀系列的 lcp ,扩展 kmp 能求的 lcp 还是有一些限制的。本题中,对于一些情况,就不得不用循环复制的方法,将问题化解。大致可以分为 3 种情况,具体就看图吧。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 100000
    #define max(x,y) x>y?x:y

    void
    get_self_lcp(char *t, int lt, int *lcp) {
        int
    j = 0, k;
        while
    (j + 1 < lt && t[j] == t[j + 1])
            ++
    j;
        lcp[1] = j; k = 1;
        for
    (int i = 2; i < lt; ++i) {
            int
    len = k + lcp[k] - 1, l = lcp[i - k];
            if
    (l < len - i + 1)
                lcp[i] = l;
            else
    {
                j = max(0, len - i + 1);
                while
    (i + j < lt && t[j] == t[i + j])
                    ++
    j;
                lcp[i] = j; k = i;
            }
        }
    }


    void
    ext_kmp(char *s, int ls, int *lcp1, char *t, int lt, int *lcp2) {
        get_self_lcp(t, lt, lcp2);
        int
    j = 0, k;
        while
    (j < ls && j < lt && s[j] == t[j])
            ++
    j;
        lcp1[0] = j; k = 0;
        for
    (int i = 1; i < ls; ++i) {
            int
    len = k + lcp1[k] - 1, l = lcp2[i - k];
            if
    (l < len - i + 1)
                lcp1[i] = l;
            else
    {
                j = max(0, len - i + 1);
                while
    (i + j < ls && j < lt && s[i + j] == t[j])
                    ++
    j;
                lcp1[i] = j; k = i;
            }
        }
    }


    int
    lcp1[MAXN + 2], lcp2[MAXN + 2];
    char
    s1[MAXN + 2], s2[MAXN + 2];

    int
    main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
        int i;
        while
    (scanf("%s%s", s1, s2) != EOF) {
            int
    len = strlen(s1), l2 = strlen(s2);
            for
    (i = 0; i < len; ++i)
                s2[i] = s2[i % l2];
            ext_kmp(s1, len, lcp1, s2, max(len, l2), lcp2);
            int
    ip = len;
            for
    (i = len - 1; i >= 0; --i) {
                int
    lm = lcp1[i];
                if
    (i + lm < ip) {
                    if
    (s2[lm] < s1[i + lm])
                        ip = i;
                }
    else {
                    if
    (ip - i >= l2) {
                        lm = lcp1[ip - l2 + 1];
                        if
    (lm < l2 && s1[ip - l2 + 1 + lm] < s2[lm])
                            ip = i;
                    }
    else {
                        lm = lcp2[ip - i];
                        if
    (lm < l2 && s2[ip - i + lm] < s2[lm])
                            ip = i;
                    }
                }
            }

            for
    (i = 0; i < ip; ++i)
                putchar(s1[i]);
            s2[l2] = 0;
            printf("%s%s\n", s2, s1 + ip);
        }

        return
    0;
    }

  • 相关阅读:
    浅谈表单同步提交和异步提交
    springboot多数据源&动态数据源(主从)
    MyBatis 中 @Param 注解的四种使用场景,最后一种经常被人忽略!
    手把手带你入门 Spring Security!
    10分钟了解JSON Web令牌(JWT)
    什么是Http无状态?Session、Cookie、Token三者之间的区别
    彻底理解cookie,session,token的区别
    56.合并区间(面试遇到的一道算法题,简述解法)
    C#object
    职称考试整理
  • 原文地址:https://www.cnblogs.com/LETTers/p/2490563.html
Copyright © 2020-2023  润新知