1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <string.h> // strcmp()

#define REP(i, b, e) for (size_t i = b; i < e; ++i)

bool compare_str(const char* s1, const char* s2)
{
    return strcmp(s1, s2) < 0;
}

void make_suffix_array(const std::string& s, std::vector<const char*>& v)
{
    v.resize(s.size());

    REP(i, 0, s.size())
    {
        v[i] = s.c_str() + i;
    }

    std::sort(v.begin(), v.end(), compare_str);
}

typedef std::vector<const char*>::const_iterator Iter;

void skip_empty_string(Iter& beg, Iter end, size_t depth)
{
    while (beg != end && (*beg)[depth] == '\0')
    {
        ++beg;
    }
}

void find_range(Iter& beg, Iter& end, size_t depth, char c)
{
    while (beg != end && (*beg)[depth] < c)
    {
        ++beg;
    }

    Iter cur = beg;

    while (cur != end && (*cur)[depth] == c)
    {
        ++cur;
    }

    end = cur;
}

void traverse(Iter beg1, Iter end1, Iter beg2, Iter end2, size_t depth, size_t& max_depth)
{
    skip_empty_string(beg1, end1, depth);

    skip_empty_string(beg2, end2, depth);

    while (beg1 != end1 && beg2 != end2)
    {
        const char c = (*beg1)[depth];

        Iter the_beg1 = beg1, the_end1 = end1;

        find_range(the_beg1, the_end1, depth, c);

        Iter the_beg2 = beg2, the_end2 = end2;

        find_range(the_beg2, the_end2, depth, c);

        if (the_beg1 != the_end1 && the_beg2 != the_end2)
        {
            max_depth = std::max(max_depth, depth + 1);

            traverse(the_beg1, the_end1, the_beg2, the_end2, depth + 1, max_depth);
        }

        beg1 = the_end1;

        beg2 = the_end2;
    }
}

int main()
{
    std::string s1, s2;

    std::getline(std::cin, s1);

    std::getline(std::cin, s2);

    std::vector<const char*> v1, v2;

    make_suffix_array(s1, v1);

    make_suffix_array(s2, v2);

    size_t max_depth = 0;

    traverse(v1.begin(), v1.end(), v2.begin(), v2.end(), 0, max_depth);

    std::cout << max_depth << std::endl;
}