█████████ ████ ███░░░░░███ ░░███ ███ ░░░ ██████ ███████ ██████ ██████ ░███ ███░░███ ███░░███ ███░░███ ███░░███ ░███ ░███ ░███░███ ░███ ░███████ ░███ ░███ ░░███ ███░███ ░███░███ ░███ ░███░░░ ░███ ░███ ░░█████████ ░░██████ ░░████████░░██████ ░░██████ ░░░░░░░░░ ░░░░░░ ░░░░░░░░ ░░░░░░ ░░░░░░

Envío 7162

Problema 0x43 - Encontrar el borde más largo de una string

  • Autor: Ikerlb
  • Fecha: 2023-10-03 05:03:39 UTC (Hace alrededor de 1 año)
Caso # Resultado Tiempo Memoria
#1
Correcto
0.015 s 3 KBi
#2
Correcto
0.016 s 3 KBi
#3
Correcto
0.02 s 3 KBi
#4
Correcto
0.017 s 3 KBi
#5
Correcto
0.018 s 3 KBi
#6
Correcto
0.016 s 3 KBi
#7
Tiempo límite excedido
1.586 s 25 KBi
#8
Tiempo límite excedido
1.573 s 25 KBi
#9
Tiempo límite excedido
1.59 s 25 KBi
#10
Tiempo límite excedido
1.569 s 25 KBi
#11
Tiempo límite excedido
1.534 s 25 KBi
#12
Tiempo límite excedido
1.563 s 25 KBi
#13
Tiempo límite excedido
1.522 s 25 KBi
#14
Tiempo límite excedido
1.56 s 26 KBi
#15
Tiempo límite excedido
1.58 s 26 KBi
#16
Tiempo límite excedido
1.59 s 25 KBi
#17
Tiempo límite excedido
1.564 s 28 KBi
#18
Tiempo límite excedido
1.583 s 31 KBi
#19
Tiempo límite excedido
1.564 s 31 KBi
#20
Tiempo límite excedido
1.551 s 32 KBi
#21
Tiempo límite excedido
1.593 s 32 KBi
#22
Tiempo límite excedido
1.572 s 25 KBi
Puntos totales: 28 / 100

Código

from sys import stdin

def get_border(s, sa, lcp):
    n = len(s)
    i = sa.index(0)
    while i > 0 and (n - sa[i - 1]) != lcp[i]:
        i -= 1
    if n - sa[i - 1] == lcp[i]:
        return (i - 1, lcp[i])
    return None

def create_lcp_array(s, sa):
    n = len(s)
    phi = [-1 for _ in range(n)]

    for i in range(1, n):
        phi[sa[i]] = sa[i - 1] 

    nlcp = [0 for _ in range(n)]
    l = 0
    for i in range(n):
        p = phi[i]
        if p == -1:
            continue
        while i + l < n and p + l < n and s[i+l] == s[p+l]:
            l += 1
        nlcp[i] = l
        l = max(0, l - 1)

    lcp = [0 for _ in range(n)]
    for i in range(n):
        lcp[i] = nlcp[sa[i]]
    return lcp

def eq(e1, e2):
    return e1[0] == e2[0] and e1[1] == e2[1]

def create_suffix_array(s):
    n = len(s)
    ra = [ord(c) for c in s]
    nra = [0 for _ in range(n)] 
    l = [[0, 0, 0] for _ in range(n)]
    k = 1
    while k <= n:
        for i in range(n):
            l[i][0] = ra[i]
            l[i][1] = ra[i + k] if i + k < n else -1
            l[i][2] = i
            nra[i] = 0

        l.sort(key = lambda e: (e[0], e[1]))

        for i in range(1, n):
            nra[l[i][2]] = nra[l[i - 1][2]] if eq(l[i], l[i - 1]) else i

        k *= 2
        ra, nra = nra, ra
    return [e[2] for e in l]

def fmt(s, sa, lcp):
    print(s)
    n = len(s)
    for i, si in enumerate(sa):
        suffix = ''.join(s[si:])
        resi = '{si:{width}}'.format(width = len(str(n)), si = si)
        res = '{res:{width}}'.format(width = n, res = suffix)
        print(f"{resi} {res} {lcp[i]}")

s = next(stdin)[:-1]
sa = create_suffix_array(s)
lcp = create_lcp_array(s, sa)
res = get_border(s, sa, lcp)
#fmt(s, sa, lcp)
if res is None:
    print(0)
else:
    print(res[1])