4
long mod = (long) (Math.pow(10, 11) + 3);10
public int longestCommonSubpath(int n, int[][] paths) {12
// min length will be 115
// max length will be the (path of min length)17
int max = Integer.MAX_VALUE;19
for (int path[] : paths) {20
max = Math.min(max, path.length);23
// now we will pre calculate the the powers of base24
// and upto max only bcoz that's the longest subarray25
// we are going to deal with26
p_i = new long[max + 1];30
for (int i = 1; i <= max; i++) {32
p_i[i] = mulmod(p_i[i - 1], p, mod);39
int mid = (min + max) / 2;41
if (solve(mid, paths)) {42
// if this length satisfies43
// we are moving to right44
// checking length greater than this56
public boolean solve(int len, int paths[][]) {58
Map<Long, Long> map = new HashMap<>();60
// now for each path we are going to calculate the61
// hash value for each subpath of length -> len62
// and store the frequency of hash in map63
// and if for a hash value the frequency equals64
// paths.length it means it exists in all path array67
for (int path[] : paths) {71
// we are using a set for storing hash value of particular len for72
// each path beacuse there is a possibility73
// that a subpath repeats multiple times74
// in a path so it directly updating in map75
// will lead to wrong count76
Set<Long> set = new HashSet<>();78
// hash is calculated as80
// (p^3 * (path[0]+1)) + (p^2 * (path[1]+1)) + (p^1 * (path[2] + 1))82
// now when we are moving forward83
// and we need to update the hash value85
// delete (p^3 * (path[index-len]+1)) from prev_hash86
// so now the hash will become ->87
// (p^2 * (path[1]+1)) + (p^1 * (path[2] + 1))88
// and then multiply prev_hash by p89
// (p^3 * (path[1]+1)) + (p^2 * (path[2] + 1))90
// now add (p^1 * (path[3]+1))92
// (p^3 * (path[1]+1)) + (p^2 * (path[2] + 1)) + (p^1 * (path[3]+1))94
// using this way we avoid calculating invmod95
// so easier to implement97
for (int i = 0; i < len; i++) {98
hash = (hash + mulmod(p_i[len - i], (path[i] + 1), mod)) % mod;103
for (int i = len; i < path.length; i++) {104
long new_hash = (hash - mulmod(p_i[len], path[i - len] + 1, mod) + mod) % mod;105
new_hash = mulmod(new_hash, p, mod);106
new_hash = (new_hash + mulmod(p_i[1], path[i] + 1, mod)) % mod;111
// now for all the hash values in the set we will update the count113
for (long hsh : set) {114
map.put(hsh, map.getOrDefault(hsh, 0l) + 1l);115
if (map.get(hsh) == paths.length) {124
public long pow(long a, long b, int mod) {132
ans = mulmod(ans, val, mod);134
val = mulmod(val, val, mod);141
long mulmod(long a, long b, long mod) {142
return ((a % mod) * (b % mod)) % mod;