Fzu2267 The Bigger the Better
题意:两个字符串,每次选一个字符串,删掉该字符,重复上述操作直到删除,最后问最小删除的最小字典序是多少
题解:每次对比字符,选择最小的字符来删,如果有相等的字符,那么就要看当前的后缀,选择字典序最小的那个后缀,后缀的字典序可以用后缀数组来搞
#include <iostream> #include <algorithm> #include <string.h> #define maxn 200100 using namespace std; struct SuffixArray { int s[maxn]; int sa[maxn],ra[maxn],height[maxn],t1[maxn],t2[maxn],c[maxn],n; void build_sa(int m) { int i,*x=t1,*y=t2; for(i=0; i<m; i++) c[i]=0; for(i=0; i<n; i++) c[x[i]=s[i]]++; for(i=1; i<m; i++) c[i]+=c[i-1]; for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i; for(int k=1; k<=n; k<<=1) { int p=0; for(i=n-k; i<n; i++) y[p++]=i; for(i=0; i<n; i++)if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0; i<m; i++) c[i]=0; for(i=0; i<n; i++) c[x[y[i]]]++; for(i=1; i<m; i++) c[i]+=c[i-1]; for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p=1,x[sa[0]]=0; for(i=1; i<n; i++) x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++; if(p>=n) break; m=p; } } void build_height() { int i,j,k=0; for(i=0; i<n; i++)ra[sa[i]]=i; for(i=0; i<n; i++) { if(k)k--; j=sa[ra[i]-1]; while(s[i+k]==s[j+k])k++; height[ra[i]]=k; } } }sa; int main(){ int T, n, m, ca = 1; ios::sync_with_stdio(0); cin>>T; while(T--){ //memset(sa.s, 0, sizeof(sa.s)); cin>>n>>m; for(int i=0;i<n;i++) cin>>sa.s[i]; sa.s[n] = sa.s[n+m+1] = 0; for(int i=n+1;i<n+m+1;i++) cin>>sa.s[i]; sa.n = n+m+2; sa.build_sa(15); sa.build_height(); int p1 = 0, p2 = n+1, num = 0; cout<<"Case "<<ca++<<": "; while(p1<n&&p2<n+m+1){ if(sa.ra[p1] > sa.ra[p2]) cout<<sa.s[p1++]; else cout<<sa.s[p2++]; } while(p1<n) cout<<sa.s[p1++]; while(p2<n+m+1) cout<<sa.s[p2++]; cout<<endl; } return 0; } /* 10 9 9 1 2 3 4 5 6 7 8 9 2 3 1 4 6 5 7 9 8 10 1 1 9 9 10 9 9 1 2 3 4 5 6 7 8 9 2 3 1 4 6 5 7 9 8 */
posted on 2018-05-07 15:16 2855669158 阅读(207) 评论(0) 编辑 收藏 举报