【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()