【HDOJ】2890 Longest Repeated subsequence

后缀数组的应用。和男人八题那个后缀数组差不多。

  1 /* 2890 */
  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 = 50050;
 44 int a[maxn], b[maxn], aa[maxn];
 45 int pos[maxn], pn;
 46 int rrank[maxn], height[maxn], sa[maxn];
 47 int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
 48 int n, k, at;
 49 
 50 bool cmp(int *r, int a, int b, int l) {
 51     return r[a]==r[b] && r[a+l]==r[b+l];
 52 }
 53 
 54 void da(int *r, int *sa, int n, int m) {
 55     int i, j, *x=wa, *y=wb, *t, p;
 56     
 57     for (i=0; i<m; ++i) wc[i] = 0;
 58     for (i=0; i<n; ++i) wc[x[i]=r[i]]++;
 59     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 60     for (i=n-1; i>=0; --i) sa[--wc[x[i]]] = i;
 61     for (j=1,p=1; p<n; j*=2, m=p) {
 62         for (p=0,i=n-j; i<n; ++i) y[p++] = i;
 63         for (i=0; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
 64         for (i=0; i<n; ++i) wv[i] = x[y[i]];
 65         for (i=0; i<m; ++i) wc[i] = 0;
 66         for (i=0; i<n; ++i) wc[wv[i]]++;
 67         for (i=1; i<m; ++i) wc[i] += wc[i-1];
 68         for (i=n-1; i>=0; --i) sa[--wc[wv[i]]] = y[i];
 69         for (t=x, x=y, y=t, i=1,p=1,x[sa[0]]=0; i<n; ++i)
 70             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1:p++;
 71     }
 72 }
 73 
 74 void calheight(int *r, int *sa, int n) {
 75     int i, j, k=0;
 76     
 77     for (i=1; i<=n; ++i) rrank[sa[i]] = i;
 78     for (i=0; i<n; height[rrank[i++]]=k)
 79     for (k?k--:0, j=sa[rrank[i]-1]; r[i+k]==r[j+k]; ++k);
 80 }
 81 
 82 bool judge(int bound) {
 83     int i = 1;
 84     int pn = 0;
 85     
 86     while (i <= n) {
 87         if (height[i] < bound) {
 88             at = sa[i-1];
 89             sort(pos, pos+pn);
 90             int kk = 1, p = pos[0];
 91             rep(j, 1, pn) {
 92                 if (pos[j]-p >= bound) {
 93                     p = pos[j];
 94                     ++kk;
 95                 }
 96             }
 97             
 98             if (kk >= k)
 99                 return true;
100             pn = 0;
101             pos[pn++] = sa[i++];
102         } else {
103             pos[pn++] = sa[i++];
104         }
105     }
106     at = sa[n-1];
107     sort(pos, pos+pn);
108     int kk = 1, p = pos[0];
109     rep(j, 1, pn) {
110         if (pos[j]-p >= bound) {
111             p = pos[j];
112             ++kk;
113         }
114     }
115     
116     if (kk >= k)
117         return true;
118     
119     return false;
120 }
121 
122 void printSa(int n) {
123     for (int i=1; i<=n; ++i)
124         printf("%d ", sa[i]);
125     putchar('\n');
126 }
127 
128 void printHeight(int n) {
129     for (int i=1; i<=n; ++i)
130         printf("%d ", height[i]);
131     putchar('\n');
132 }
133 
134 void solve() {
135     sort(b, b+n);
136     int nn = unique(b, b+n) - b;
137     
138     rep(i, 0, n)
139         aa[i] = lower_bound(b, b+nn, a[i]) - b + 1;
140     aa[n] = 0;
141     
142     da(aa, sa, n+1, nn+4);
143     calheight(aa, sa, n);
144     
145     #ifndef ONLINE_JUDGE
146         // printSa(n);
147         // printHeight(n);
148     #endif
149     
150     int l = 1, r = n, mid;
151     int ans = 0, fr;
152     
153     while (l <= r) {
154         mid = (l + r) >> 1;
155         if (judge(mid)) {
156             ans = mid;
157             fr = at;
158             l = mid + 1;
159         } else {
160             r = mid - 1;
161         }
162     }
163     
164     printf("%d\n", ans);
165     rep(i, 0, ans)
166         printf("%d\n", b[aa[fr+i]-1]);
167 }
168 
169 int main() {
170     ios::sync_with_stdio(false);
171     #ifndef ONLINE_JUDGE
172         freopen("data.in", "r", stdin);
173         freopen("data.out", "w", stdout);
174     #endif
175     
176     int t;
177     
178     scanf("%d", &t);
179     while (t--) {
180         scanf("%d %d", &n, &k);
181         rep(i, 0, n) {
182             scanf("%d", &a[i]);
183             b[i] = a[i];
184         }
185         solve();
186         if (t)
187             putchar('\n');
188     }
189     
190     #ifndef ONLINE_JUDGE
191         printf("time = %d.\n", (int)clock());
192     #endif
193     
194     return 0;
195 }

 

你可能感兴趣的:(【HDOJ】2890 Longest Repeated subsequence)