【HDOJ】4691 Front compression
后缀数组基础题目,dc3解。
1 /* 4691 */ 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 maxl = 1e5+5; 45 const int maxn = 1e5+5; 46 char s[maxl]; 47 int nw; 48 int A[maxn], B[maxn]; 49 int a[maxn*3]; 50 int height[maxn], rrank[maxn], sa[maxn*3]; 51 int wa[maxn], wb[maxn], wc[maxn], wv[maxn]; 52 int dp[maxn][17]; 53 54 bool c0(int *r, int a, int b) { 55 return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2]; 56 } 57 58 bool c12(int k, int *r, int a, int b) { 59 if (k == 2) 60 return r[a]<r[b] || (r[a]==r[b] && c12(1, r, a+1, b+1)); 61 else 62 return r[a]<r[b] || (r[a]==r[b] && wv[a+1]<wv[b+1]); 63 } 64 65 void sort(int *r, int *a, int *b, int n, int m) { 66 int i; 67 68 for (i=0; i<n; ++i) wv[i] = r[a[i]]; 69 for (i=0; i<m; ++i) wc[i] = 0; 70 for (i=0; i<n; ++i) wc[wv[i]]++; 71 for (i=1; i<m; ++i) wc[i] += wc[i-1]; 72 for (i=n-1; i>=0; --i) b[--wc[wv[i]]] = a[i]; 73 } 74 75 #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb)) 76 #define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2) 77 void dc3(int *r, int *sa, int n, int m) { 78 int i, j, *rn=r+n, *san=sa+n, ta=0, tb=(n+1)/3, tbc=0, p; 79 80 r[n] = r[n+1] = 0; 81 for (i=0; i<n; ++i) if (i%3!=0) wa[tbc++] = i; 82 sort(r+2, wa, wb, tbc, m); 83 sort(r+1, wb, wa, tbc, m); 84 sort(r, wa, wb, tbc, m); 85 for (p=1, rn[F(wb[0])]=0, i=1; i<tbc; ++i) 86 rn[F(wb[i])] = c0(r, wb[i-1], wb[i]) ? p-1:p++; 87 if (p < tbc) 88 dc3(rn, san, tbc, p); 89 else 90 for (i=0; i<tbc; ++i) san[rn[i]] = i; 91 for (i=0; i<tbc; ++i) 92 if (san[i] < tb) 93 wb[ta++] = san[i] * 3; 94 if (n%3 == 1) 95 wb[ta++] = n - 1; 96 sort(r, wb, wa, ta, m); 97 for (i=0; i<tbc; ++i) wv[wb[i]=G(san[i])] = i; 98 for (i=0,j=0,p=0; i<ta && j<tbc; ++p) 99 sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; 100 while (i < ta) sa[p++] = wa[i++]; 101 while (j < tbc) sa[p++] = wb[j++]; 102 } 103 104 void calheight(int *r, int *sa, int n) { 105 int i, j, k = 0; 106 107 for (i=1; i<=n; ++i) rrank[sa[i]] = i; 108 for (i=0; i<n; height[rrank[i++]]=k) 109 for (k?k--:0, j=sa[rrank[i]-1]; r[j+k]==r[i+k]; ++k) ; 110 } 111 112 void init_RMQ(int n) { 113 int i, j; 114 115 for (i=1; i<=n; ++i) 116 dp[i][0] = height[i]; 117 dp[1][0] = INF; 118 for (j=1; (1<<j)<=n; ++j) 119 for (i=1; i+(1<<j)-1<=n; ++i) 120 dp[i][j] = min(dp[i][j-1], 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 return min(dp[l][k], dp[r-(1<<k)+1][k]); 134 } 135 136 void printSa(int n) { 137 for (int i=1; i<=n; ++i) 138 printf("%d ", sa[i]); 139 putchar('\n'); 140 } 141 142 void printRank(int n) { 143 for (int i=1; i<=n; ++i) 144 printf("%d ", rrank[i]); 145 putchar('\n'); 146 } 147 148 void printHeight(int n) { 149 for (int i=1; i<=n; ++i) 150 printf("%d ", height[i]); 151 putchar('\n'); 152 } 153 154 int getBit(int x) { 155 if (x == 0) 156 return 1; 157 158 int ret = 0; 159 160 while (x) { 161 ++ret; 162 x /= 10; 163 } 164 165 return ret; 166 } 167 168 void solve() { 169 int n = 0; 170 171 for (int i=0; ; ++i) { 172 if (s[i] == '\0') { 173 n = i; 174 break; 175 } 176 a[i] = s[i] - 'a' + 1; 177 } 178 a[n] = 0; 179 180 dc3(a, sa, n+1, 30); 181 calheight(a, sa, n); 182 183 #ifndef ONLINE_JUDGE 184 // printSa(n); 185 // printRank(n); 186 // printHeight(n); 187 #endif 188 189 init_RMQ(n); 190 191 __int64 ansa, ansb; 192 int pl, l, mnl, tmp; 193 194 pl = B[0] - A[0]; 195 ansa = pl; 196 ansb = pl + 2; 197 198 rep(i, 1, nw) { 199 l = B[i] - A[i]; 200 mnl = min(l, pl); 201 if (A[i] == A[i-1]) { 202 tmp = mnl; 203 } else { 204 tmp = RMQ(rrank[A[i-1]], rrank[A[i]]); 205 if (tmp > mnl) 206 tmp = mnl; 207 } 208 #ifndef ONLINE_JUDGE 209 // printf("%d: tmp = %d\n", i, tmp); 210 #endif 211 ansa += l; 212 ansb += getBit(tmp) + 1 + l - tmp; 213 pl = l; 214 } 215 216 ansa += nw; 217 ansb += nw; 218 219 printf("%I64d %I64d\n", ansa, ansb); 220 } 221 222 int main() { 223 ios::sync_with_stdio(false); 224 #ifndef ONLINE_JUDGE 225 freopen("data.in", "r", stdin); 226 freopen("data.out", "w", stdout); 227 #endif 228 229 while (scanf("%s", s) != EOF) { 230 scanf("%d", &nw); 231 rep(i, 0, nw) 232 scanf("%d %d", &A[i], &B[i]); 233 solve(); 234 } 235 236 #ifndef ONLINE_JUDGE 237 printf("time = %d.\n", (int)clock()); 238 #endif 239 240 return 0; 241 }
数据生成器。
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 lc = list(string.lowercase) 11 for tt in xrange(t): 12 length = randint(50, 105) 13 line = "" 14 for i in xrange(length): 15 idx = randint(0, 10) 16 line += lc[idx] 17 fout.write("%s\n" % (line)) 18 n = randint(1, 20) 19 fout.write("%d\n" % (n)) 20 for i in xrange(n): 21 a = randint(0, length-1) 22 b = randint(a+1, length) 23 fout.write("%d %d\n" % (a, b)) 24 25 26 def MovDataIn(): 27 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 28 shutil.copyfile("data.in", desFileName) 29 30 31 if __name__ == "__main__": 32 GenDataIn() 33 MovDataIn()