【HDOJ】3553 Just a String

后缀数组加二分可解。

  1 /* 3553 */
  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 = 100005;
 44 const int maxn = maxl;
 45 int a[maxn*3];
 46 int rrank[maxn], height[maxn], sa[maxn*3];
 47 int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
 48 int dp[maxn][17];
 49 __int64 tot[maxn];
 50 char s[maxl];
 51 __int64 kth;
 52 
 53 bool c0(int *r, int a, int b) {
 54     return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2];
 55 }
 56 
 57 bool c12(int k, int *r, int a, int b) {
 58     if (k == 2)
 59         return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1));
 60     else
 61         return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]);
 62 }
 63 
 64 void sort(int *r, int *a, int *b, int n, int m) {
 65     int i;
 66     
 67     for (i=0; i<n; ++i) wv[i] = r[a[i]];
 68     for (i=0; i<m; ++i) wc[i] = 0;
 69     for (i=0; i<n; ++i) wc[wv[i]]++;
 70     for (i=1; i<m; ++i) wc[i] += wc[i-1];
 71     for (i=n-1; i>=0; --i) b[--wc[wv[i]]] = a[i];
 72 }
 73 
 74 #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb))
 75 #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2)
 76 void dc3(int *r, int *sa, int n, int m) {
 77     int i, j, *rn=r+n, *san=sa+n, ta=0, tb=(n+1)/3, tbc=0, p;
 78     
 79     r[n] = r[n+1] = 0;
 80     for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i;
 81     sort(r+2, wa, wb, tbc, m);
 82     sort(r+1, wb, wa, tbc, m);
 83     sort(r, wa, wb, tbc, m);
 84     for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i)
 85         rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1 : p++;
 86     if (p < tbc)
 87         dc3(rn, san, tbc, p);
 88     else
 89         for (i=0; i<tbc; ++i) san[rn[i]] = i;
 90     for (i=0; i<tbc; ++i)
 91         if (san[i] < tb)
 92             wb[ta++] = san[i] * 3;
 93     if (n%3 == 1)
 94         wb[ta++] = n - 1;
 95     sort(r, wb, wa, ta, m);
 96     for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])] = i;
 97     for (i=0,j=0,p=0; i<ta && j<tbc; ++p)
 98         sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
 99     while (i < ta) sa[p++] = wa[i++];
100     while (j < tbc) sa[p++] = wb[j++];
101 }
102 
103 void calheight(int *r, int *sa, int n) {
104     int i, j, k = 0;
105     
106     for (i=1; i<=n; ++i) rrank[sa[i]] = i;
107     for (i=0; i<n; height[rrank[i++]]=k)
108     for (k?k--:0, j=sa[rrank[i]-1]; r[j+k]==r[i+k]; ++k) ;
109 }
110 
111 void init_RMQ(int n) {
112     int i, j;
113     
114     for (i=1; i<=n; ++i) dp[i][0] = i;
115     for (j=1; (1<<j)<=n; ++j)
116         for (i=1; i+(1<<j)-1<=n; ++i)
117             if (height[dp[i][j-1]] < height[dp[i+(1<<(j-1))][j-1]])
118                 dp[i][j] = dp[i][j-1];
119             else
120                 dp[i][j] = dp[i+(1<<(j-1))][j-1];
121 }
122 
123 int RMQ(int l, int r) {
124     if (l > r)
125         swap(l, r);
126     
127     ++l;
128     int k = 0;
129     
130     while (1<<(k+1) <= r-l+1)
131         ++k;
132     
133     if (height[dp[l][k]] < height[dp[r-(1<<k)+1][k]])
134         return dp[l][k];
135     else
136         return dp[r-(1<<k)+1][k];
137 }
138 
139 void printSa(int n) {
140     for (int i=1; i<=n; ++i)
141         printf("%d ", sa[i]);
142     putchar('\n');
143 }
144 
145 void printHeight(int n) {
146     for (int i=1; i<=n; ++i)
147         printf("%d ", height[i]);
148     putchar('\n');
149 }
150 
151 void solve() {
152     int n = 0;
153     
154     for (int i=0; ; ++i) {
155         if (s[i] == '\0') {
156             n = i;
157             break;
158         }
159         a[i] = s[i];
160     }
161     a[n] = 0;
162     
163     dc3(a, sa, n+1, 130);
164     calheight(a, sa, n);
165     init_RMQ(n);
166     
167     rep(i, 1, n+1)
168         tot[i] = tot[i-1] + n - sa[i];
169         
170     int l = 1, r = n, mid, idx;
171     int pre = 0;
172     int pos = 0, len;
173     __int64 tmp;
174     
175     while (l < r) {
176         idx = RMQ(l, r);
177         mid = idx - 1;
178         tmp = 1LL * (height[idx] - pre) * (r-l+1);
179         if (kth <= tmp) {
180             pos = l;
181             len = pre + (kth+r-l)/(r-l+1);
182             break;
183         }
184         kth -= tmp;
185         tmp = tot[mid] - tot[l-1] - 1LL * height[idx] * (mid-l+1);
186         if (kth <= tmp) {
187             r = mid;
188         } else {
189             kth -= tmp;
190             l = mid + 1;
191         }
192         pre = height[idx];
193     }
194     
195     if (pos == 0) {
196         pos = l;
197         len = pre + kth;
198     }
199     
200     rep(i, 0, len)
201         putchar(s[sa[pos]+i]);
202     putchar('\n');
203 }
204 
205 int main() {
206     ios::sync_with_stdio(false);
207     #ifndef ONLINE_JUDGE
208         freopen("data.in", "r", stdin);
209         freopen("data.out", "w", stdout);
210     #endif
211     
212     int t;
213     
214     scanf("%d", &t);
215     rep(tt, 1, t+1) {
216         scanf("%s %I64d", s, &kth);
217         printf("Case %d: ", tt);
218         solve();
219     }
220     
221     #ifndef ONLINE_JUDGE
222         printf("time = %d.\n", (int)clock());
223     #endif
224     
225     return 0;
226 }

数据生成器。

 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         uc = list(string.uppercase)
11         fout.write("%d\n" % (t))
12         for tt in xrange(t):
13             n = randint(100, 200)
14             kth = randint(1, n*(n+1)/2)
15             line = ""
16             for i in xrange(n):
17                 idx = randint(0, 25)
18                 line += uc[idx]
19             fout.write("%s %d\n" % (line, kth))
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()

 

posted on 2016-02-05 00:55  Bombe  阅读(148)  评论(0编辑  收藏  举报

导航