出现或者反转后出现在每个字符串中的最长子串
题目链接:https://cn.vjudge.net/contest/318888#problem/M
思路:
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <math.h> 7 #include <queue> 8 #include <set> 9 10 #define INF 0x3f3f3f3f 11 #define pii pair<int,int> 12 #define LL long long 13 using namespace std; 14 typedef unsigned long long ull; 15 const int MAXN = 2e5 + 10; 16 int t; 17 int wa[MAXN], wb[MAXN], wv[MAXN], ws_[MAXN]; 18 void Suffix(int *r, int *sa, int n, int m) 19 { 20 int i, j, k, *x = wa, *y = wb, *t; 21 for(i = 0; i < m; ++i) ws_[i] = 0; 22 for(i = 0; i < n; ++i) ws_[x[i] = r[i]]++; 23 for(i = 1; i < m; ++i) ws_[i] += ws_[i - 1]; 24 for(i = n - 1; i >= 0; --i) sa[--ws_[x[i]]] = i; 25 for(j = 1, k = 1; k < n; j *= 2, m = k) 26 { 27 for(k = 0, i = n - j; i < n; ++i) y[k++] = i; 28 for(i = 0; i < n; ++i) if(sa[i] >= j) y[k++] = sa[i] - j; 29 for(i = 0; i < n; ++i) wv[i] = x[y[i]]; 30 for(i = 0; i < m; ++i) ws_[i] = 0; 31 for(i = 0; i < n; ++i) ws_[wv[i]]++; 32 for(i = 1; i < m; ++i) ws_[i] += ws_[i - 1]; 33 for(i = n - 1; i >= 0; --i) sa[--ws_[wv[i]]] = y[i]; 34 t = x; 35 x = y; 36 y = t; 37 for(x[sa[0]] = 0, i = k = 1; i < n; ++i) 38 x[sa[i]] = (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j]) ? k - 1 : k++; 39 } 40 } 41 int Rank[MAXN], height[MAXN], sa[MAXN], r[MAXN]; 42 char s[MAXN]; 43 int indexx[MAXN],vis[200]; 44 void calheight(int *r,int *sa,int n) 45 { 46 int i,j,k=0; 47 for(i=1; i<=n; i++)Rank[sa[i]]=i; 48 for(i=0; i<n; height[Rank[i++]]=k) 49 for(k?k--:0,j=sa[Rank[i]-1]; r[i+k]==r[j+k]; k++); 50 } 51 52 bool check(int x,int n){ 53 int tot = 0; 54 memset(vis,0, sizeof(vis)); 55 for (int i=1;i<n;i++){ 56 if (height[i]>=x){ 57 for (int j=0;j<t;j++) { 58 if (indexx[sa[i]] == j) { 59 tot += (vis[j] ? 0 : 1); 60 vis[j] = 1; 61 } 62 if (indexx[sa[i - 1]] == j) { 63 tot += (vis[j] ? 0 : 1); 64 vis[j] = 1; 65 } 66 } 67 } 68 else{ 69 if (tot>=t) 70 return true; 71 tot = 0; 72 memset(vis,0, sizeof(vis)); 73 } 74 } 75 if (tot>=t) 76 return true; 77 return false; 78 } 79 80 81 int main() 82 { 83 int T; 84 scanf("%d",&T); 85 while (T--) { 86 scanf("%d",&t); 87 int XX = 1; 88 int n = 0; 89 for (int i=0;i<t;i++){ 90 scanf("%s",s); 91 int len = strlen(s); 92 for (int j=0;j<len;j++){ 93 r[n++] = s[j]; 94 indexx[n-1] = i; 95 } 96 indexx[n] = i; 97 r[n++] = 128+XX++; 98 reverse(s,s+len); 99 for (int j=0;j<len;j++){ 100 r[n++] = s[j]; 101 indexx[n-1] = i; 102 } 103 indexx[n] = i; 104 r[n++] = 128+XX++; 105 } 106 r[n] = 0; 107 Suffix(r,sa,n+1,128+XX+1); 108 calheight(r,sa,n); 109 int L=1,R=n,mid,len=0; 110 while (L<=R){ 111 mid = (L+R)>>1; 112 if (check(mid,n)){ 113 len = mid; 114 L = mid+1; 115 }else 116 R = mid-1; 117 } 118 printf("%d\n",len); 119 } 120 return 0; 121 }