2
def longestCommonSubpath(self, n, paths) -> int:3
def get_common_subpath_hashes(k):4
"""Return hash values of common subpaths of length k, or empty set if none exists"""6
def get_subpath_hashes(path):7
hash, coeff = 0, pow(n, k - 1, mod)8
for i in range(len(path) + 1):10
hash = (hash * n + path[i]) % mod14
hash = ((hash - coeff * path[i - k]) * n + path[i]) % mod16
return reduce(set.intersection, (set(get_subpath_hashes(p)) for p in paths))18
# can be replaced with a pre-computed large prime19
mod = self._generate_large_prime(int(1e18), int(9e18))20
low, high = 1, min(len(p) for p in paths) + 122
mid = (low + high) // 223
if get_common_subpath_hashes(mid):29
def _generate_large_prime(self, lower, upper):30
"""Generate a prime between [lower, upper)"""32
def is_prime(n, trials=50):37
if x == 1 and x0 != 1 and x0 != n - 1:40
return True if x0 != 1 else False45
return not any(witness(randrange(1, n), n) for _ in range(trials))48
r for r in iter(lambda: randrange(lower, upper), None) if is_prime(r)