后缀数组。
1 /* 3294 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int maxl = 1005; 44 const int maxs = 105; 45 const int maxn = maxl * maxs; 46 char s[maxs][maxl]; 47 int id[maxn], pos[maxn], pn; 48 bool visit[maxs]; 49 int a[maxn]; 50 int rank[maxn], height[maxn], sa[maxn]; 51 int wa[maxn], wb[maxn], wc[maxn], wv[maxn]; 52 int ns, ns_; 53 54 bool cmp(int *r, int a, int b, int l) { 55 return r[a]==r[b] && r[a+l]==r[b+l]; 56 } 57 58 void da(int *r, int *sa, int n, int m) { 59 int i, j, *x=wa, *y=wb, *t, p; 60 61 for (i=0; i<m; ++i) wc[i] = 0; 62 for (i=0; i<n; ++i) wc[x[i]=r[i]]++; 63 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 64 for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i; 65 for (j=1,p=1; p<n; j*=2,m=p) { 66 for (p=0,i=n-j; i<n; ++i) y[p++] = i; 67 for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i]-j; 68 for (i=0; i<n; ++i) wv[i] = x[y[i]]; 69 for (i=0; i<m; ++i) wc[i] = 0; 70 for (i=0; i<n; ++i) wc[wv[i]]++; 71 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 72 for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i]; 73 for (t=x,x=y,y=t, x[sa[0]]=0, p=1, i=1; i<n; ++i) 74 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++; 75 } 76 } 77 78 void calheight(int *r, int *sa, int n) { 79 int i, j, k = 0; 80 81 for (i=1; i<=n; ++i) rank[sa[i]] = i; 82 for (i=0; i<n; height[rank[i++]]=k) 83 for (k?k--:0, j=sa[rank[i]-1]; r[j+k]==r[i+k]; ++k) ; 84 } 85 86 bool check(int b, int e) { 87 int cnt = 0; 88 89 memset(visit, false, sizeof(visit)); 90 rep(i, b, e+1) { 91 if (!visit[id[sa[i]]]) { 92 visit[id[sa[i]]] = true; 93 ++cnt; 94 } 95 } 96 97 return cnt > ns_; 98 } 99 100 bool judge(int bound, int n) { 101 bool ret = false; 102 int b, e; 103 104 b = e = 0; 105 rep(i, 1, n+1) { 106 if (height[i] >= bound) { 107 e = i; 108 } else { 109 if (check(b, e)) { 110 if (!ret) 111 pn = 0; 112 ret = true; 113 pos[pn++] = sa[b]; 114 } 115 b = e = i; 116 } 117 } 118 if (check(b, e)) { 119 if (!ret) 120 pn = 0; 121 ret = true; 122 pos[pn++] = sa[b]; 123 } 124 125 return ret; 126 } 127 128 void printSa(int n) { 129 for (int i=1; i<=n; ++i) 130 printf("%d ", sa[i]); 131 putchar(‘\n‘); 132 } 133 134 void printHeight(int n) { 135 for (int i=1; i<=n; ++i) 136 printf("%d ", height[i]); 137 putchar(‘\n‘); 138 } 139 140 void solve() { 141 int n = 0, ml = 0; 142 143 if (ns == 1) { 144 puts(s[0]); 145 return ; 146 } 147 148 rep(i, 0, ns) { 149 for (int j=0; ; ++j) { 150 if (s[i][j] == ‘\0‘) { 151 ml = max(ml, j); 152 break; 153 } 154 id[n] = i; 155 a[n] = s[i][j] - ‘a‘ + 100; 156 ++n; 157 } 158 id[n] = a[n] = i; 159 ++n; 160 } 161 162 --n; 163 da(a, sa, n+1, 130); 164 calheight(a, sa, n); 165 166 #ifndef ONLINE_JUDGE 167 // printSa(n); 168 // printHeight(n); 169 // printf("ml = %d\n", ml); 170 #endif 171 172 int l = 1, r = ml, mid; 173 int ans = 0; 174 ns_ = ns >> 1; 175 176 while (l <= r) { 177 mid = (l + r) >> 1; 178 if (judge(mid, n)) { 179 ans = mid; 180 l = mid + 1; 181 } else { 182 r = mid - 1; 183 } 184 } 185 186 if (ans == 0) { 187 puts("?"); 188 return ; 189 } 190 191 char ch; 192 193 rep(i, 0, pn) { 194 rep(j, 0, ans) { 195 ch = a[pos[i]+j] - 100 + ‘a‘; 196 putchar(ch); 197 } 198 putchar(‘\n‘); 199 } 200 } 201 202 int main() { 203 ios::sync_with_stdio(false); 204 #ifndef ONLINE_JUDGE 205 freopen("data.in", "r", stdin); 206 freopen("data.out", "w", stdout); 207 #endif 208 209 int t = 0; 210 211 while (scanf("%d", &ns)!=EOF && ns) { 212 rep(i, 0, ns) 213 scanf("%s", s[i]); 214 if (t++) 215 putchar(‘\n‘); 216 solve(); 217 } 218 219 #ifndef ONLINE_JUDGE 220 printf("time = %d.\n", (int)clock()); 221 #endif 222 223 return 0; 224 }
数据生成器。
1 from random import randint, shuffle 2 import shutil 3 import string 4 5 6 def GenDataIn(): 7 with open("data.in", "w") as fout: 8 t = 20 9 bound = 10**3 10 lc = list(string.lowercase) 11 for tt in xrange(t): 12 n = randint(1, 10) 13 fout.write("%d\n" % (n)) 14 for i in xrange(n): 15 length = randint(20, 50) 16 line = "" 17 for j in xrange(length): 18 idx = randint(0, 25) 19 line += lc[idx] 20 fout.write("%s\n" % (line)) 21 fout.write("0\n") 22 23 24 def MovDataIn(): 25 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 26 shutil.copyfile("data.in", desFileName) 27 28 29 if __name__ == "__main__": 30 GenDataIn() 31 MovDataIn()
时间: 2024-11-03 03:44:35