Skibidi String #13091

Skibidi String (Editorial)

Problem Author:

Hasan Saleh (MathModel)

Prepared by:

Hasan Saleh (MathModel)

Edited by:

Hasan Saleh (MathModel)

The problem can be shortened into , Given a binary string of length n-2 , Construct the lexicographically smallest string such that every window s_is_{i+1}s_{i+2} has f(s_is_{i+1}s_{i+2}) \bmod 2=t_i.

First let's understand on a string of length , there are only three shapes : all equal () gives f=3 , exactly two equal (\mathtt{aab},\mathtt{aba},\mathtt{abb}) gives f=5 and all distinct () gives f=6 , Therefore t_i=0 exactly when s_i,s_{i+1},s_{i+2} are pairwise distinct , and t_i=1 exactly when the window has a repeated letter.

So only equalities between letters matter , and a window never needs more than distinct letters , which means the alphabet \{\mathtt{a},\mathtt{b},\mathtt{c}\} is enough , We precompute all windows over \{\mathtt{a},\mathtt{b},\mathtt{c}\} grouped by f \bmod 2 in lexicographic order.

Now we build greedily from left to right , each time taking the smallest letter that keeps the current window correct , However plain greedy fails : for t=\mathtt{10} the smallest first window is , but then can never be all distinct , The future can get stuck only when t_{i+1}=0 while s_{i+1}=s_{i+2} , since once s_{i+1}\neq s_{i+2} there is always a third letter in \{\mathtt{a},\mathtt{b},\mathtt{c}\} completing a distinct window , and a window with t=1 can always be completed by repeating a letter , Therefore greedy with the one-step lookahead

t_{i+1}=0 \implies s_{i+1}\neq s_{i+2}

never gets stuck , and since every choice is the smallest letter that still leaves a valid completion , the resulting string is the lexicographically smallest.

Complexity O(27n)=O(n).

from collections import defaultdict as dd 
get=dd(list)

def f(s):
    st=set()
    for i in range(len(s)):
        for j in range(i,len(s)):
            st.add(s[i:j+1])
    return len(st)

for a in range(97,100):
    for b in range(97,100):
        for c in range(97,100):
            s=chr(a)+chr(b)+chr(c)
            get[f(s)%2].append(s)

def ok(j,i,t):
    return i+1>=len(t) or t[i+1]=='1' or j[1]!=j[2]

def solve():
    n=int(input())
    t=input()
    a=[j for j in get[int(t[0])] if ok(j,0,t)][0]
    for i in range(1,n-2):
        for j in get[int(t[i])]:
            if(a[-2]==j[0] and a[-1]==j[1] and ok(j,i,t)):
                a+=j[2]

                break
    print(a)

for _ in range(int(input())):
    solve()