后缀数组基础题目。
倍增法解。
1 /* 1743 */ 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 maxn = 20005; 44 int a[maxn], b[maxn]; 45 int rank[maxn], sa[maxn], height[maxn]; 46 int wa[maxn], wb[maxn], wv[maxn], wc[maxn]; 47 int n; 48 49 bool cmp(int *r, int a, int b, int l) { 50 return r[a]==r[b] && r[a+l]==r[b+l]; 51 } 52 53 void da(int *r, int* sa, int n, int m) { 54 int i, j, p, *x=wa, *y=wb, *t; 55 56 for (i=0; i<m; ++i) wc[i] = 0; 57 for (i=0; i<n; ++i) wc[x[i]=r[i]]++; 58 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 59 for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i; 60 for (j=1,p=1; p<n; j*=2, m=p) { 61 for (p=0,i=n-j; i<n; ++i) y[p++] = i; 62 for (i=0; i<n; ++i) if (sa[i]>=j) y[p++] = sa[i]-j; 63 for (i=0; i<n; ++i) wv[i] = x[y[i]]; 64 for (i=0; i<m; ++i) wc[i] = 0; 65 for (i=0; i<n; ++i) wc[wv[i]]++; 66 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 67 for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i]; 68 for (t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; ++i) 69 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++; 70 } 71 } 72 73 void calheight(int *r, int* sa, int n) { 74 int i, j, k = 0; 75 76 for (i=1; i<=n; ++i) rank[sa[i]] = i; 77 for (i=0; i<n; height[rank[i++]]=k) 78 for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k) ; 79 } 80 81 void printSa(int n) { 82 puts("sa ="); 83 rep(i, 1, n+1) 84 printf("%d ", sa[i]); 85 putchar('\n'); 86 } 87 88 void printHeight(int n) { 89 puts("height ="); 90 rep(i, 1, n+1) 91 printf("%d ", height[i]); 92 putchar('\n'); 93 } 94 95 bool judge(int bound) { 96 int mx = INT_MIN, mn = INT_MAX; 97 98 rep(i, 1, n+1) { 99 if (height[i] >= bound) { 100 mx = max(mx, sa[i]); 101 mn = min(mn, sa[i]); 102 if (mx-mn >= bound) 103 return true; 104 } else { 105 mx = mn = sa[i]; 106 } 107 } 108 109 return false; 110 } 111 112 void solve() { 113 rep(i, 0, n-1) 114 b[i] = a[i] - a[i+1] + 90; 115 b[n-1] = 0; 116 da(b, sa, n, 200); 117 calheight(b, sa, --n); 118 119 #ifndef ONLINE_JUDGE 120 // printSa(n); 121 // printHeight(n); 122 #endif 123 124 int l = 4, r = n, mid; 125 int ans = -1; 126 127 while (l <= r) { 128 mid = (l + r) >> 1; 129 if (judge(mid)) { 130 ans = mid; 131 l = mid + 1; 132 } else { 133 r = mid - 1; 134 } 135 } 136 137 printf("%d\n", ans+1); 138 } 139 140 int main() { 141 ios::sync_with_stdio(false); 142 #ifndef ONLINE_JUDGE 143 freopen("data.in", "r", stdin); 144 freopen("data.out", "w", stdout); 145 #endif 146 147 while (scanf("%d", &n)!=EOF && n) { 148 rep(i, 0, n) 149 scanf("%d", &a[i]); 150 solve(); 151 } 152 153 #ifndef ONLINE_JUDGE 154 printf("time = %d.\n", (int)clock()); 155 #endif 156 157 return 0; 158 }
DC3解。
1 /* 1743 */ 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 maxn = 20005; 44 int a[maxn], b[maxn*3]; 45 int rank[maxn], sa[maxn*3], height[maxn]; 46 int wa[maxn], wb[maxn], wv[maxn], wc[maxn]; 47 int n; 48 49 bool c0(int *r, int a, int b) { 50 return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2]; 51 } 52 53 bool c12(int k, int *r, int a, int b) { 54 if (k == 2) 55 return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1)); 56 else 57 return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]); 58 } 59 60 void sort(int *r, int *a, int *b, int n, int m) { 61 int i; 62 63 for (i=0; i<n; ++i) wv[i] = r[a[i]]; 64 for (i=0; i<m; ++i) wc[i] = 0; 65 for (i=0; i<n; ++i) wc[wv[i]]++; 66 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 67 for (i=n-1; i>=0; --i) b[--wc[wv[i]]] = a[i]; 68 } 69 70 #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb)) 71 #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2) 72 void dc3(int *r, int* sa, int n, int m) { 73 int i, j, *rn = r + n, *san = sa + n; 74 int ta = 0, tb = (n + 1) / 3, tbc = 0, p; 75 76 r[n] = r[n+1] = 0; 77 for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i; 78 sort(r+2, wa, wb, tbc, m); 79 sort(r+1, wb, wa, tbc, m); 80 sort(r, wa, wb, tbc, m); 81 for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i) 82 rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1:p++; 83 if (p < tbc) 84 dc3(rn, san, tbc, p); 85 else 86 for (i=0; i<tbc; ++i) san[rn[i]] = i; 87 for (i=0; i<tbc; ++i) 88 if (san[i] < tb) 89 wb[ta++] = san[i] * 3; 90 if (n%3 == 1) 91 wb[ta++] = n-1; 92 sort(r, wb, wa, ta, m); 93 for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])]=i; 94 for (i=0,j=0,p=0; i<ta&&j<tbc; ++p) 95 sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; 96 while (i < ta) sa[p++] = wa[i++]; 97 while (j < tbc) sa[p++] = wb[j++]; 98 } 99 100 void calheight(int *r, int* sa, int n) { 101 int i, j, k = 0; 102 103 for (i=1; i<=n; ++i) rank[sa[i]] = i; 104 for (i=0; i<n; height[rank[i++]]=k) 105 for (k?k--:0, j=sa[rank[i]-1]; r[i+k]==r[j+k]; ++k) ; 106 } 107 108 void printSa(int n) { 109 puts("sa ="); 110 rep(i, 1, n+1) 111 printf("%d ", sa[i]); 112 putchar('\n'); 113 } 114 115 void printHeight(int n) { 116 puts("height ="); 117 rep(i, 1, n+1) 118 printf("%d ", height[i]); 119 putchar('\n'); 120 } 121 122 bool judge(int bound) { 123 int mx = INT_MIN, mn = INT_MAX; 124 125 rep(i, 1, n+1) { 126 if (height[i] >= bound) { 127 mx = max(mx, sa[i]); 128 mn = min(mn, sa[i]); 129 if (mx-mn >= bound) 130 return true; 131 } else { 132 mx = mn = sa[i]; 133 } 134 } 135 136 return false; 137 } 138 139 void solve() { 140 rep(i, 0, n-1) 141 b[i] = a[i] - a[i+1] + 90; 142 b[n-1] = 0; 143 dc3(b, sa, n, 200); 144 calheight(b, sa, --n); 145 146 #ifndef ONLINE_JUDGE 147 printSa(n); 148 printHeight(n); 149 #endif 150 151 int l = 4, r = n, mid; 152 int ans = -1; 153 154 while (l <= r) { 155 mid = (l + r) >> 1; 156 if (judge(mid)) { 157 ans = mid; 158 l = mid + 1; 159 } else { 160 r = mid - 1; 161 } 162 } 163 164 printf("%d\n", ans+1); 165 } 166 167 int main() { 168 ios::sync_with_stdio(false); 169 #ifndef ONLINE_JUDGE 170 freopen("data.in", "r", stdin); 171 freopen("data.out", "w", stdout); 172 #endif 173 174 while (scanf("%d", &n)!=EOF && n) { 175 rep(i, 0, n) 176 scanf("%d", &a[i]); 177 solve(); 178 } 179 180 #ifndef ONLINE_JUDGE 181 printf("time = %d.\n", (int)clock()); 182 #endif 183 184 return 0; 185 }
数据发生器。
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 = 88 10 for tt in xrange(t): 11 n = randint(1000, 5000) 12 fout.write("%d\n" % (n)) 13 dataList = [] 14 for i in xrange(n): 15 x = randint(1, bound) 16 dataList.append(x) 17 fout.write(" ".join(map(str, dataList)) + "\n") 18 fout.write("0\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()