Background
Problem
Input
Output
Example
input | output |
---|---|
28 VOTEFORTHEGREATALBANIAFORYOU CHOOSETHEGREATALBANIANFUTURE |
THEGREATAL |
题意:
找到最长公共子序列并输出。
灵感:
这个题只有一个最长公共子序列。如果有多个的时候而且要求最小字典序,可以排序或许建立字典树找到最小字典序的最长公共子序列。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=4100000; char str1[maxn],str2[maxn]; int L,L1,L2,ch[maxn]; struct SA { int cntA[maxn],cntB[maxn],A[maxn],B[maxn]; int rank[maxn],sa[maxn],tsa[maxn],ht[maxn]; void sort() { for (int i = 0; i <= 27; i ++) cntA[i] = 0; for (int i = 1; i <= L; i ++) cntA[ch[i]] ++; for (int i = 1; i <= 27; i ++) cntA[i] += cntA[i - 1]; for (int i = L; i; i --) sa[cntA[ch[i]] --] = i; rank[sa[1]] = 1; for (int i = 2; i <= L; i ++){ rank[sa[i]] = rank[sa[i - 1]]; if (ch[sa[i]] != ch[sa[i - 1]]) rank[sa[i]] ++; } for (int l = 1; rank[sa[L]] < L; l <<= 1){ for (int i = 0; i <= L; i ++) cntA[i] = 0; for (int i = 0; i <= L; i ++) cntB[i] = 0; for ( int i = 1; i <= L; i ++){ cntA[A[i] = rank[i]] ++; cntB[B[i] = (i + l <= L) ? rank[i + l] : 0] ++; } for (int i = 1; i <= L; i ++) cntB[i] += cntB[i - 1]; for (int i = L; i; i --) tsa[cntB[B[i]] --] = i; for (int i = 1; i <= L; i ++) cntA[i] += cntA[i - 1]; for (int i = L; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i]; rank[sa[1]] = 1; for (int i = 2; i <= L; i ++){ rank[sa[i]] = rank[sa[i - 1]]; if (A[sa[i]] != A[sa[i - 1]] || B[sa[i]] != B[sa[i - 1]]) rank[sa[i]] ++; } } } void getht() { for (int i = 1, j = 0; i <= L; i ++){ if (j) j --; while (ch[i + j] == ch[sa[rank[i] - 1] + j]) j ++; ht[rank[i]] = j; } } }; SA Sa; void init() { scanf("%d",&L1); scanf("%s",str1+1); scanf("%s",str2+1); L1=strlen(str1+1); L2=strlen(str2+1); for(int i=1;i<=L1;i++) ch[i]=str1[i]-'A'+1; ch[L1+1]=27; for(int i=1;i<=L2;i++) ch[i+L1+1]=str2[i]-'A'+1; L=L1+L2+1; } int main() { init(); Sa.sort(); Sa.getht(); int ans=0,pos=0; for(int i = 1; i <= L; i++){ if((Sa.sa[i]<=L1)!=(Sa.sa[i-1]<=L1)) if(Sa.ht[i]>ans){ ans=Sa.ht[i];pos=Sa.sa[i]; } } for(int i=pos;i<=pos+ans-1;i++) printf("%c",ch[i]+'A'-1); return 0; }