2
const long p1 = 1299827; /// 1299827; 299807; 199807;3
const long p2 = 1e9 + 7;12
int minsize(vector<vector<int>> &paths) {14
for (auto v : paths) {15
msize = min(msize, int(v.size()));20
bool collision(vector<vector<int>> &paths, int len, Hit &hit, int row, int col) {21
if (hit.count == 0) return false;22
if (hit.row == row) return true; // what should we do for internal collisions?23
auto &v1 = paths[hit.row];24
auto &v2 = paths[row];25
for (int i = 0, c1 = hit.col, c2 = col; i < len; i++, c1++, c2++)26
if (v1[c1] != v2[c2]) return true;30
bool rabinkarp(vector<vector<int>> &paths, int len) {31
unordered_map<long, Hit> hits;34
for (int i = 0; i < len - 1; i++) power = (power * p1) % p2;36
for (int i = 0, j = 0, found = 0; i < paths.size(); i++, j = 0, found = 0) {39
while (j < paths[i].size()) {40
if (j >= len) hash = (hash + p2 - (paths[i][j - len] * power) % p2) % p2; // remove item41
hash = (hash * p1 + paths[i][j++]) % p2; // add item42
if (j >= len && (i == 0 || hits.count(hash))) {43
auto &hit = hits[hash];44
if (!collision(paths, len, hit, i, j - len)) {45
hit.count += 1, hit.row = i, hit.col = j - len;46
if (hit.count == paths.size()) return true;51
if (found == 0) break; // no match/s so give up...57
int longestCommonSubpath(int n, vector<vector<int>> &paths) {58
int lo = 1, hi = minsize(paths), found = 0;61
int len = lo + (hi - lo) / 2;63
if (rabinkarp(paths, len)) {