【HDOJ】2459 Maximum repetition substring
后缀数组+RMQ。
1 /* 2459 */ 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 INF = 0x3f3f3f3f; 44 const int maxn = 1e5+5; 45 char s[maxn]; 46 int a[maxn]; 47 int rrank[maxn], height[maxn], sa[maxn]; 48 int wa[maxn], wb[maxn], wc[maxn], wv[maxn]; 49 int dp[maxn][17]; 50 int mx[maxn], L[maxn]; 51 52 bool cmp(int *r, int a, int b, int l) { 53 return r[a]==r[b] && r[a+l]==r[b+l]; 54 } 55 56 void da(int *r, int *sa, int n, int m) { 57 int i, j, *x=wa, *y=wb, *t, p; 58 59 for (i=0; i<m; ++i) wc[i] = 0; 60 for (i=0; i<n; ++i) wc[x[i]=r[i]]++; 61 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 62 for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i; 63 for (j=1,p=1; p<n; j*=2, m=p) { 64 for (p=0,i=n-j; i<n; ++i) y[p++] = i; 65 for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; 66 for (i=0; i<n; ++i) wv[i] = x[y[i]]; 67 for (i=0; i<m; ++i) wc[i] = 0; 68 for (i=0; i<n; ++i) wc[x[i]]++; 69 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 70 for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i]; 71 for (t=x, x=y, y=t, p=1, i=1, x[sa[0]]=0; i<n; ++i) 72 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++; 73 } 74 } 75 76 void calheight(int *r, int *sa, int n) { 77 int i, j, k = 0; 78 79 for (i=1; i<=n; ++i) rrank[sa[i]] = i; 80 for (i=0; i<n; height[rrank[i++]]=k) 81 for (k?k--:0, j=sa[rrank[i]-1]; r[j+k]==r[i+k]; ++k) ; 82 } 83 84 void init_RMQ(int n) { 85 int i, j; 86 87 for (i=1; i<=n; ++i) 88 dp[i][0] = height[i]; 89 dp[1][0] = INF; 90 for (j=1; (1<<j)<=n; ++j) 91 for (i=1; i+(1<<j)-1<=n; ++i) 92 dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]); 93 } 94 95 int RMQ(int l, int r) { 96 if (l > r) 97 swap(l, r); 98 99 int k = 0; 100 ++l; 101 while (1<<(k+1) <= r-l+1) 102 ++k; 103 104 return min(dp[l][k], dp[r-(1<<k)+1][k]); 105 } 106 107 void printSa(int n) { 108 for (int i=1; i<=n; ++i) 109 printf("%d ", sa[i]); 110 putchar('\n'); 111 } 112 113 void printHeight(int n) { 114 for (int i=1; i<=n; ++i) 115 printf("%d ", height[i]); 116 putchar('\n'); 117 } 118 119 void solve() { 120 int n; 121 122 for (int i=0; ; ++i) { 123 if (s[i] == '\0') { 124 n = i; 125 break; 126 } 127 a[i] = s[i] - 'a' + 1; 128 } 129 a[n] = 0; 130 131 da(a, sa, n+1, 30); 132 calheight(a, sa, n); 133 init_RMQ(n); 134 135 int n_ = n >> 1, tmp; 136 rep(i, 1, n_) { 137 mx[i] = 0; 138 for (int p=0, q=i; q<n; p=q, q+=i) { 139 tmp = RMQ(rrank[p], rrank[q]); 140 mx[i] = max(mx[i], tmp/i+1); 141 if (tmp%i) { 142 tmp = RMQ(rrank[p-(i-tmp%i)], rrank[q-(i-tmp%i)]); 143 mx[i] = max(mx[i], tmp/i+1); 144 } 145 } 146 } 147 148 int ans = 0; 149 rep(i, 1, n_) 150 ans = max(ans, mx[i]); 151 152 int ln = 0; 153 rep(i, 1, n_) { 154 if (mx[i] == ans) { 155 L[ln++] = i; 156 } 157 } 158 159 int beg = 0, len = 0; 160 161 rep(i, 1, n+1) { 162 rep(j, 0, ln) { 163 int p = sa[i]; 164 if (p+L[j] >= n) 165 continue; 166 167 tmp = RMQ(rrank[p], rrank[p+L[j]]); 168 if (tmp/L[j]+1 >= ans) { 169 beg = p; 170 len = L[j] * ans; 171 goto _output; 172 } 173 } 174 } 175 176 _output: 177 s[beg+len] = '\0'; 178 puts(s+beg); 179 } 180 181 int main() { 182 ios::sync_with_stdio(false); 183 #ifndef ONLINE_JUDGE 184 freopen("data.in", "r", stdin); 185 freopen("data.out", "w", stdout); 186 #endif 187 188 int t = 0; 189 190 while (scanf("%s", s)!=EOF && (s[0]!='#')) { 191 printf("Case %d: ", ++t); 192 solve(); 193 } 194 195 #ifndef ONLINE_JUDGE 196 printf("time = %d.\n", (int)clock()); 197 #endif 198 199 return 0; 200 }
数据生成器。
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**2 10 lc = list(string.lowercase) 11 for tt in xrange(t): 12 length = randint(100, 500) 13 line = "" 14 for i in xrange(length): 15 idx = randint(0, 25) 16 line += lc[idx] 17 fout.write("%s\n" % line) 18 fout.write("#\n") 19 20 21 def MovDataIn(): 22 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 23 shutil.copyfile("data.in", desFileName) 24 25 26 if __name__ == "__main__": 27 GenDataIn() 28 MovDataIn()