yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
27
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 210000; 18 int n,k,_rank[maxn],sa[maxn],lcp[maxn]; 19 char str[maxn]; 20 bool cmp_sa(int i,int j) { 21 if(_rank[i] != _rank[j]) return _rank[i] < _rank[j]; 22 int ri = i + k < n ? _rank[i+k]:0; 23 int rj = j + k < n ? _rank[j+k]:0; 24 return ri < rj; 25 } 26 void construct_sa(char *s) { 27 n = strlen(s); 28 memset(sa,0,sizeof(sa)); 29 for(int i = 0; i < n; i++) { 30 sa[i] = i; 31 _rank[i] = s[i]; 32 } 33 for(k = 1; k < n; k <<= 1) { 34 sort(sa,sa+n,cmp_sa); 35 lcp[sa[0]] = 0; 36 for(int i = 1; i < n; i++) 37 lcp[sa[i]] = lcp[sa[i-1]] + cmp_sa(sa[i-1],sa[i]); 38 for(int i = 0; i < n; i++) 39 _rank[i] = lcp[i]; 40 } 41 } 42 void construct_lcp(char *s) { 43 memset(lcp,0,sizeof(lcp)); 44 for(int i = 0,h = 0; i < n; i++) { 45 if(h) h--; 46 for(int j = sa[_rank[i]+1]; i+h < n && j + h < n && s[i+h] == s[j+h]; h++); 47 lcp[_rank[i]+1] = h; 48 } 49 } 50 int main() { 51 int len,ans; 52 gets(str); 53 len = strlen(str); 54 str[len] = '+'; 55 gets(str+len+1); 56 construct_sa(str); 57 construct_lcp(str); 58 ans = 0; 59 for(int i = 1; i < n; i++) 60 if((sa[i] < len) != (sa[i-1] < len)) ans = max(ans,lcp[i]); 61 printf("%d\n",ans); 62 return 0; 63 }
快一点的做法
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 200020; 18 int wa[maxn],wb[maxn],wv[maxn],wss[maxn],rk[maxn],lcp[maxn]; 19 bool cmp(int *r,int i,int j,int k) { 20 return r[i] == r[j] && r[i+k] == r[j+k]; 21 } 22 void da(int *r,int *sa,int n,int m) { 23 int i,k,p,*x = wa,*y = wb; 24 for(i = 0; i < m; ++i) wss[i] = 0; 25 for(i = 0; i < n; ++i) wss[x[i] = r[i]]++; 26 for(i = 1; i < m; ++i) wss[i] += wss[i-1]; 27 for(i = n-1; i >= 0; --i) sa[--wss[x[i]]] = i; 28 29 for(p = k = 1; p < n; k <<= 1,m = p) { 30 for(p = 0, i = n - k; i < n; ++i) y[p++] = i; 31 for(i = 0; i < n; ++i) if(sa[i] >= k) y[p++] = sa[i] - k; 32 33 for(i = 0; i < m; ++i) wss[i] = 0; 34 for(i = 0; i < n; ++i) wv[i] = x[y[i]]; 35 36 for(i = 0; i < n; ++i) wss[wv[i]]++; 37 for(i = 1; i < m; ++i) wss[i] += wss[i-1]; 38 for(i = n-1; i >= 0; --i) sa[--wss[wv[i]]] = y[i]; 39 40 swap(x,y); 41 x[sa[0]] = 0; 42 for(p = i = 1; i < n; ++i) 43 x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p++; 44 45 } 46 47 } 48 void calclcp(int *r,int *sa,int n) { 49 for(int i = 1; i <= n; ++i) rk[sa[i]] = i; 50 int h = 0; 51 for(int i = 0; i < n; ++i) { 52 if(h) h--; 53 int j = sa[rk[i]-1]; 54 for(; j+h < n&& i+h < n; ++h) 55 if(r[i+h] != r[j+h]) break; 56 lcp[rk[i]-1] = h; 57 } 58 } 59 char str[maxn],tmp[maxn]; 60 int r[maxn],sa[maxn]; 61 int main() { 62 while(~scanf("%s",str)) { 63 int len = strlen(str); 64 str[len] = '#'; 65 scanf("%s",str+len+1); 66 for(int i = 0; str[i]; ++i) r[i] = str[i]; 67 da(r,sa,strlen(str)+1,128); 68 calclcp(r,sa,strlen(str)); 69 int ans = 0; 70 for(int i = 1; str[i]; ++i) 71 if(sa[i] < len && sa[i+1] > len || sa[i] > len && sa[i+1] < len) 72 ans = max(ans,lcp[i]); 73 printf("%d\n",ans); 74 } 75 return 0; 76 }
采用hash+二分也是可以顺利AC的。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef unsigned long long ULL; 7 const int maxn = 100010; 8 const ULL B = 1000003; 9 ULL base[maxn] = {1},hs[maxn]; 10 char *a = NULL,*b = NULL; 11 int n,m; 12 bool calc(int len){ 13 ULL tmp = hs[0] = 0; 14 for(int i = 0; i < len; ++i){ 15 hs[0] = hs[0]*B + b[i]; 16 tmp = tmp*B + a[i]; 17 } 18 for(int i = 0; i + len < m; ++i) 19 hs[i+1] = hs[i]*B + b[i + len] - b[i]*base[len]; 20 sort(hs,hs + m -len + 1); 21 for(int i = 0; i + len <= n; ++i){ 22 if(binary_search(hs,hs+m-len+1,tmp)) return true; 23 tmp = tmp*B + a[i + len] - a[i]*base[len]; 24 } 25 return false; 26 } 27 int main(){ 28 for(int i = 1; i < maxn; ++i) 29 base[i] = base[i-1]*B; 30 a = new char[maxn]; 31 b = new char[maxn]; 32 while(~scanf("%s%s",a,b)){ 33 n = strlen(a); 34 m = strlen(b); 35 if(n > m){ 36 swap(n,m); 37 swap(a,b); 38 } 39 int ans = 0,low = 0,high = n; 40 while(low <= high){ 41 int mid = (low + high)>>1; 42 if(calc(mid)){ 43 ans = mid; 44 low = mid + 1; 45 }else high = mid - 1; 46 } 47 printf("%d\n",ans); 48 } 49 delete []a; 50 delete []b; 51 return 0; 52 }