1 class Solution {
2 public:
3 typedef pair<int,int> pii;
4 const int k1=1331;
5 const int k2=13331;
6 const int mod1=1e9+7;
7 const int mod2=1e9+9;
8 int p1[100005],p2[100005];
9 struct pairhash {
10 size_t operator() (const pair<int, int>& p) const {
11 auto fn = hash<int>();
12 return (fn(p.first) <<16) ^ fn(p.second);
13 }
14 };
15
16 int longestCommonSubpath(int n, vector<vector<int>>& paths) {
17 p1[0]=p2[0]=1;
18 for(int i=1;i<=100001;i++)
19 {
20 p1[i]=1ll*p1[i-1]*k1%mod1;
21 p2[i]=1ll*p2[i-1]*k2%mod2;
22 }
23 int row=paths.size();
24 vector<int>s1[row+1];
25 vector<int>s2[row+1];
26 for(int i=1;i<=row;i++)s2[i]=s1[i]=vector<int>(paths[i-1].size()+1);
27 for(int i=1;i<=row;i++)
28 {
29 int sz=paths[i-1].size();
30 for(int j=1;j<=sz;j++)
31 {
32 s1[i][j]=((1ll*s1[i][j-1]*k1%mod1)+paths[i-1][j-1])%mod1;
33 s2[i][j]=((1ll*s2[i][j-1]*k2%mod2)+paths[i-1][j-1])%mod2;
34 }
35 }
36
37 function<int(int)>check=[&](int len)
38 {
39 unordered_map<pii,int,pairhash>mp;
40
41 for(int i=1;i+len-1<=paths[0].size();i++)
42 {
43 int j=i+len-1;
44 int x1=((s1[1][j]-(1ll*s1[1][i-1]*p1[j-i+1]%mod1))%mod1+mod1)%mod1;
45 int x2=((s2[1][j]-(1ll*s2[1][i-1]*p2[j-i+1]%mod2))%mod2+mod2)%mod2;
46 mp[{x1,x2}]=1;
47 }
48
49 for(int x=2;x<=row;x++)
50 {
51 unordered_map<pii,int,pairhash>vis;
52 int sz=paths[x-1].size();
53 bool ok=false;
54 for(int i=1;i+len-1<=sz;i++)
55 {
56 int j=i+len-1;
57 int t1=((s1[x][j]-(1ll*s1[x][i-1]*p1[j-i+1]%mod1))%mod1+mod1)%mod1;
58 int t2=((s2[x][j]-(1ll*s2[x][i-1]*p2[j-i+1]%mod2))%mod2+mod2)%mod2;
59 if(mp[{t1,t2}]&&!vis[{t1,t2}]){mp[{t1,t2}]++;vis[{t1,t2}]=1;}
60 }
61 }
62 for(auto &p:mp)if(p.second==row)return 1;
63 return 0;
64 };
65 int l=0,r=1e6;
66 while(l<=r)
67 {
68 int mid=(l+r)>>1;
69 if(check(mid))l=mid+1;
70 else r=mid-1;
71 }
72 return r;
73 }
74 };