【HDOJ】4333 Revolving Digits
扩展KMP基础题目。
1 /* 4333 */ 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 = 1e5+5; 44 char s[maxl], d[maxl*2]; 45 int nxt[maxl]; 46 int Next[maxl]; 47 int Ext[maxl*2]; 48 int slen, dlen; 49 50 void getNxt(char *s, int len) { 51 int i = 0, j = -1; 52 53 nxt[0] = -1; 54 while (i < len) { 55 if (j==-1 || s[i]==s[j]) { 56 ++i; 57 ++j; 58 nxt[i] = j; 59 } else { 60 j = nxt[j]; 61 } 62 } 63 } 64 65 void getNext(char *s, int len) { 66 int i = 0, j, k, p; 67 int L; 68 69 Next[0] = len; 70 while (i<len-1 && s[i]==s[i+1]) 71 ++i; 72 Next[1] = i; 73 k = 1; 74 75 for (i=2; i<len; ++i) { 76 p = k + Next[k] - 1; 77 L = Next[i - k]; 78 if (i+L <= p) { 79 Next[i] = L; 80 } else { 81 j = p-i+1>0 ? p-i+1:0; 82 while (i+j<len && s[i+j]==s[j]) 83 ++j; 84 Next[i] = j; 85 k = i; 86 } 87 } 88 } 89 90 void getExtend(char *d, int dlen, char *s, int slen) { 91 int i = 0, j, k, p; 92 int L; 93 int mnl = min(dlen, slen); 94 95 while (i<mnl && d[i]==s[i]) 96 ++i; 97 Ext[0] = i; 98 k = 0; 99 100 for (i=1; i<dlen; ++i) { 101 p = k + Ext[k] - 1; 102 L = Next[i - k]; 103 if (i+L <= p) { 104 Ext[i] = L; 105 } else { 106 j = (p-i+1)>0 ? p-i+1:0; 107 while (i+j<dlen && j<slen && d[i+j]==s[j]) 108 ++j; 109 Ext[i] = j; 110 k = i; 111 } 112 } 113 } 114 115 void solve() { 116 strcpy(d, s); 117 strcat(d, s); 118 slen = strlen(s); 119 dlen = slen << 1; 120 121 getNext(s, slen); 122 getExtend(d, dlen, s, slen); 123 getNxt(s, slen); 124 125 int mod = slen - nxt[slen]; 126 int tmp = 1; 127 if (slen%mod == 0) 128 tmp = slen / mod; 129 130 int ln, en, gn; 131 132 ln = gn = en = 0; 133 rep(i, 0, slen) { 134 if (Ext[i] >= slen) 135 ++en; 136 else if (d[i+Ext[i]] < s[Ext[i]]) 137 ++ln; 138 else 139 ++gn; 140 } 141 142 ln /= tmp; 143 en /= tmp; 144 gn /= tmp; 145 printf("%d %d %d\n", ln, en, gn); 146 } 147 148 int main() { 149 ios::sync_with_stdio(false); 150 #ifndef ONLINE_JUDGE 151 freopen("data.in", "r", stdin); 152 freopen("data.out", "w", stdout); 153 #endif 154 155 int t; 156 157 scanf("%d", &t); 158 rep(tt, 1, t+1) { 159 scanf("%s", s); 160 printf("Case %d: ", tt); 161 solve(); 162 } 163 164 #ifndef ONLINE_JUDGE 165 printf("time = %d.\n", (int)clock()); 166 #endif 167 168 return 0; 169 }