转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Time Limit: 4000MS | Memory Limit: 131072K | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
Source
题意:
求两个字符串的最长公共子串。
分析:
将两个字符串中间用一个不会出现的'$'符号连接,然后求出lcp,最大的且相邻的两个后缀不属于同一个字符串的就是答案。
用的是DC3
1 #include <iostream> 2 #include <sstream> 3 #include <ios> 4 #include <iomanip> 5 #include <functional> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <list> 10 #include <queue> 11 #include <deque> 12 #include <stack> 13 #include <set> 14 #include <map> 15 #include <cstdio> 16 #include <cstdlib> 17 #include <cmath> 18 #include <cstring> 19 #include <climits> 20 #include <cctype> 21 using namespace std; 22 #define XINF INT_MAX 23 #define INF 0x3FFFFFFF 24 #define MP(X,Y) make_pair(X,Y) 25 #define PB(X) push_back(X) 26 #define REP(X,N) for(int X=0;X<N;X++) 27 #define REP2(X,L,R) for(int X=L;X<=R;X++) 28 #define DEP(X,R,L) for(int X=R;X>=L;X--) 29 #define CLR(A,X) memset(A,X,sizeof(A)) 30 #define IT iterator 31 typedef long long ll; 32 typedef pair<int,int> PII; 33 typedef vector<PII> VII; 34 typedef vector<int> VI; 35 #define MAXN 400010 36 37 #define F(x) ((x)/3+((x)%3==1?0:tb)) 38 #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) 39 int wa[MAXN*2],wb[MAXN*2],wv[MAXN*2],ww[MAXN*2]; 40 41 int c0(int *r, int a, int b) { 42 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 43 } 44 int c12(int k, int *r, int a, int b) 45 { 46 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 47 else return r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1]; 48 } 49 void rsort(int *r, int *a, int *b, int n, int m) { 50 REP(i,n) wv[i]=r[a[i]]; 51 REP(i,m) ww[i]=0; 52 REP(i,n) ww[wv[i]]++; 53 REP(i,m-1) ww[i+1]+=ww[i]; 54 DEP(i,n-1,0) b[--ww[wv[i]]]=a[i]; 55 } 56 57 void dc3(int *r, int *sa, int n, int m) { 58 int j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 59 r[n]=r[n+1]=0; 60 REP(i,n) if(i%3!=0) wa[tbc++]=i; 61 rsort(r+2,wa,wb,tbc,m); 62 rsort(r+1,wb,wa,tbc,m); 63 rsort(r,wa,wb,tbc,m); 64 for(p=1,rn[F(wb[0])]=0,j=1;j<tbc;j++) 65 rn[F(wb[j])]=c0(r,wb[j-1],wb[j])?p-1:p++; 66 if(p<tbc) dc3(rn,san,tbc,p); 67 else REP(i,tbc) san[rn[i]]=i; 68 REP(i,tbc) if(san[i]<tb) wb[ta++]=san[i]*3; 69 if(n%3==1) wb[ta++]=n-1; 70 rsort(r,wb,wa,ta,m); 71 REP(i,tbc) wv[wb[i]=G(san[i])]=i; 72 int i; 73 for(i=j=p=0;i<ta&&j<tbc;p++) 74 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 75 for(;i<ta;p++) sa[p]=wa[i++]; 76 for(;j<tbc;p++) sa[p]=wb[j++]; 77 } 78 79 int ra[MAXN*2], height[MAXN*2]; 80 void calheight(int *r,int *sa,int n) { 81 int i,j,k=0; 82 for(i=1;i<=n;i++) ra[sa[i]]=i; 83 for(i=0;i<n;height[ra[i++]]=k) 84 for(k?k--:0,j=sa[ra[i]-1];r[i+k]==r[j+k];k++); 85 } 86 int sa[MAXN *2]; 87 char str[MAXN]; 88 char s[MAXN]; 89 int a[MAXN]; 90 int main() 91 { 92 ios::sync_with_stdio(false); 93 while(scanf("%s",str)!=EOF){ 94 scanf("%s",s); 95 int len2=strlen(s); 96 int len1=strlen(str); 97 for(int i=0;i<len2;i++){ 98 str[i+len1]=s[i]; 99 } 100 str[len1+len2]='\0'; 101 int len=len1+len2; 102 for(int i=0;i<len;i++){ 103 a[i]=str[i]-'a'+1; 104 } 105 a[len]=0; 106 dc3(a,sa,len+1,30); 107 calheight(a,sa,len); 108 int ans=0; 109 for(int i=1;i<len;i++){ 110 if(sa[i]<len1&&sa[i-1]>=len1||(sa[i]>=len1&&sa[i-1]<len1)){ 111 ans=max(height[i],ans); 112 } 113 } 114 printf("%d\n",ans); 115 } 116 117 return 0; 118 }
利用后缀自动机的话,以一个串建一个自动机,然后另一个串直接塞进去跑就行了。相当裸
1 #include <iostream> 2 #include <sstream> 3 #include <ios> 4 #include <iomanip> 5 #include <functional> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <list> 10 #include <queue> 11 #include <deque> 12 #include <stack> 13 #include <set> 14 #include <map> 15 #include <cstdio> 16 #include <cstdlib> 17 #include <cmath> 18 #include <cstring> 19 #include <climits> 20 #include <cctype> 21 using namespace std; 22 #define XINF INT_MAX 23 #define INF 0x3FFFFFFF 24 #define MP(X,Y) make_pair(X,Y) 25 #define PB(X) push_back(X) 26 #define REP(X,N) for(int X=0;X<N;X++) 27 #define REP2(X,L,R) for(int X=L;X<=R;X++) 28 #define DEP(X,R,L) for(int X=R;X>=L;X--) 29 #define CLR(A,X) memset(A,X,sizeof(A)) 30 #define IT iterator 31 #define RIT reverse_iterator 32 typedef long long ll; 33 typedef unsigned long long ull; 34 typedef pair<int,int> PII; 35 typedef vector<PII> VII; 36 typedef vector<int> VI; 37 #define X first 38 #define Y second 39 #define lson(X) ((X)<<1) 40 #define rson(X) ((X)<<1|1) 41 42 #define MAXN 100010 43 44 //#define SUFFIX_TREE 45 46 struct SAM{ 47 SAM* go[26]; 48 SAM* par; 49 int maxl; 50 #ifdef SUFFIX_TREE 51 int st_head; 52 #endif 53 SAM(int l=0):maxl(l) { 54 #ifdef SUFFIX_TREE 55 st_head = 0; 56 #endif 57 } 58 SAM& operator=(const SAM& s){ 59 maxl = s.maxl; 60 par = s.par; 61 memcpy(go, s.go, sizeof(go)); 62 return *this; 63 #ifdef SUFFIX_TREE 64 st_head = s.st_head; 65 #endif 66 } 67 int minl() { 68 return par?par->maxl+1:maxl; 69 } 70 } node[MAXN<<1], *last, *root; 71 int n_node; 72 73 SAM* newnode() { 74 return &node[n_node++]; 75 } 76 77 void init_sam() { 78 n_node = 0; 79 last = root = newnode(); 80 } 81 82 void extend(int c) { 83 SAM* p = last, *np = newnode(); 84 np->maxl = p->maxl + 1; 85 for(; p && !p->go[c]; p = p->par) p->go[c] = np; 86 if(!p) np->par = root; 87 else { 88 SAM* q = p->go[c]; 89 if(q->maxl == p->maxl + 1) np->par = q; 90 else { 91 SAM* nq = newnode(); 92 *nq = *q; 93 nq->maxl = p->maxl + 1; 94 np->par = q->par = nq; 95 for(;p && p->go[c] == q ;p = p->par) p->go[c] = nq; 96 } 97 } 98 last = np; 99 #ifdef SUFFIX_TREE 100 last->st_head = 1; 101 #endif 102 } 103 104 string str; 105 106 #ifdef SUFFIX_TREE 107 108 VI Map[MAXN<<1]; 109 110 void init_suffixtree(char* s) { 111 init_sam(); 112 int l = strlen(s); 113 REP(i,l) extend(s[l-i-1]); 114 REP(i,n_node) Map[i].clear(); 115 REP(i,n_node) if(node[i].st_head) { 116 SAM* p = &node[i]; 117 while(p!=root) { 118 string ss = str.substr(p->minl()-1,p->maxl-p->minl()+1); 119 reverse(ss.begin(),ss.end()); 120 cout<<ss<<" -> "; 121 p=p->par; 122 } 123 cout<<"|"<<endl; 124 } 125 } 126 127 #endif 128 129 char s[MAXN]; 130 131 int main() 132 { 133 while(~scanf("%s",s)) { 134 init_sam(); 135 for(int i=0;s[i];i++) extend(s[i]-'a'); 136 scanf("%s",s); 137 int ans = 0; 138 int l = 0; 139 SAM* now = root; 140 for(int i=0;s[i];i++) { 141 s[i]-='a'; 142 while(now!=root && now->go[s[i]]==NULL) { 143 now = now->par; 144 l = min(l, now->maxl); 145 } 146 l++; 147 if(now->go[s[i]]) now = now->go[s[i]]; 148 else l=0; 149 ans = max(ans, l); 150 } 151 printf("%d\n", ans); 152 } 153 return 0; 154 }