@@ -102,25 +102,286 @@ tags:
102
102
#### Python3
103
103
104
104
``` python
105
-
105
+ class Hashing :
106
+ __slots__ = [" mod" , " h" , " p" ]
107
+
108
+ def __init__ (self , s : List[str ], base : int , mod : int ):
109
+ self .mod = mod
110
+ self .h = [0 ] * (len (s) + 1 )
111
+ self .p = [1 ] * (len (s) + 1 )
112
+ for i in range (1 , len (s) + 1 ):
113
+ self .h[i] = (self .h[i - 1 ] * base + ord (s[i - 1 ])) % mod
114
+ self .p[i] = (self .p[i - 1 ] * base) % mod
115
+
116
+ def query (self , l : int , r : int ) -> int :
117
+ return (self .h[r] - self .h[l - 1 ] * self .p[r - l + 1 ]) % self .mod
118
+
119
+
120
+ class Solution :
121
+ def minValidStrings (self , words : List[str ], target : str ) -> int :
122
+ def f (i : int ) -> int :
123
+ l, r = 0 , min (n - i, m)
124
+ while l < r:
125
+ mid = (l + r + 1 ) >> 1
126
+ sub = hashing.query(i + 1 , i + mid)
127
+ if sub in s[mid]:
128
+ l = mid
129
+ else :
130
+ r = mid - 1
131
+ return l
132
+
133
+ base, mod = 13331 , 998244353
134
+ hashing = Hashing(target, base, mod)
135
+ m = max (len (w) for w in words)
136
+ s = [set () for _ in range (m + 1 )]
137
+ for w in words:
138
+ h = 0
139
+ for j, c in enumerate (w, 1 ):
140
+ h = (h * base + ord (c)) % mod
141
+ s[j].add(h)
142
+ ans = last = mx = 0
143
+ n = len (target)
144
+ for i in range (n):
145
+ dist = f(i)
146
+ mx = max (mx, i + dist)
147
+ if i == last:
148
+ if i == mx:
149
+ return - 1
150
+ last = mx
151
+ ans += 1
152
+ return ans
106
153
```
107
154
108
155
#### Java
109
156
110
157
``` java
111
-
158
+ class Hashing {
159
+ private final long [] p;
160
+ private final long [] h;
161
+ private final long mod;
162
+
163
+ public Hashing (String word , long base , int mod ) {
164
+ int n = word. length();
165
+ p = new long [n + 1 ];
166
+ h = new long [n + 1 ];
167
+ p[0 ] = 1 ;
168
+ this . mod = mod;
169
+ for (int i = 1 ; i <= n; i++ ) {
170
+ p[i] = p[i - 1 ] * base % mod;
171
+ h[i] = (h[i - 1 ] * base + word. charAt(i - 1 )) % mod;
172
+ }
173
+ }
174
+
175
+ public long query (int l , int r ) {
176
+ return (h[r] - h[l - 1 ] * p[r - l + 1 ] % mod + mod) % mod;
177
+ }
178
+ }
179
+
180
+ class Solution {
181
+ private Hashing hashing;
182
+ private Set<Long > [] s;
183
+
184
+ public int minValidStrings (String [] words , String target ) {
185
+ int base = 13331 , mod = 998244353 ;
186
+ hashing = new Hashing (target, base, mod);
187
+ int m = Arrays . stream(words). mapToInt(String :: length). max(). orElse(0 );
188
+ s = new Set [m + 1 ];
189
+ Arrays . setAll(s, k - > new HashSet<> ());
190
+ for (String w : words) {
191
+ long h = 0 ;
192
+ for (int j = 0 ; j < w. length(); j++ ) {
193
+ h = (h * base + w. charAt(j)) % mod;
194
+ s[j + 1 ]. add(h);
195
+ }
196
+ }
197
+
198
+ int ans = 0 ;
199
+ int last = 0 ;
200
+ int mx = 0 ;
201
+ int n = target. length();
202
+ for (int i = 0 ; i < n; i++ ) {
203
+ int dist = f(i, n, m);
204
+ mx = Math . max(mx, i + dist);
205
+ if (i == last) {
206
+ if (i == mx) {
207
+ return - 1 ;
208
+ }
209
+ last = mx;
210
+ ans++ ;
211
+ }
212
+ }
213
+ return ans;
214
+ }
215
+
216
+ private int f (int i , int n , int m ) {
217
+ int l = 0 , r = Math . min(n - i, m);
218
+ while (l < r) {
219
+ int mid = (l + r + 1 ) >> 1 ;
220
+ long sub = hashing. query(i + 1 , i + mid);
221
+ if (s[mid]. contains(sub)) {
222
+ l = mid;
223
+ } else {
224
+ r = mid - 1 ;
225
+ }
226
+ }
227
+ return l;
228
+ }
229
+ }
112
230
```
113
231
114
232
#### C++
115
233
116
234
``` cpp
117
-
235
+ class Hashing {
236
+ private:
237
+ vector<long long > p;
238
+ vector<long long > h;
239
+ long long mod;
240
+
241
+ public:
242
+ Hashing(const string& word, long long base, int mod) {
243
+ int n = word.size();
244
+ p.resize(n + 1);
245
+ h.resize(n + 1);
246
+ p[ 0] = 1;
247
+ this->mod = mod;
248
+ for (int i = 1; i <= n; i++) {
249
+ p[ i] = (p[ i - 1] * base) % mod;
250
+ h[ i] = (h[ i - 1] * base + word[ i - 1] ) % mod;
251
+ }
252
+ }
253
+
254
+ long long query(int l, int r) {
255
+ return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
256
+ }
257
+ };
258
+
259
+ class Solution {
260
+ public:
261
+ int minValidStrings(vector<string >& words, string target) {
262
+ int base = 13331, mod = 998244353;
263
+ Hashing hashing(target, base, mod);
264
+ int m = 0, n = target.size();
265
+ for (const string& word : words) {
266
+ m = max(m, (int) word.size());
267
+ }
268
+
269
+ vector<unordered_set<long long>> s(m + 1);
270
+ for (const string& w : words) {
271
+ long long h = 0;
272
+ for (int j = 0; j < w.size(); j++) {
273
+ h = (h * base + w[j]) % mod;
274
+ s[j + 1].insert(h);
275
+ }
276
+ }
277
+
278
+ auto f = [&](int i) -> int {
279
+ int l = 0, r = min(n - i, m);
280
+ while (l < r) {
281
+ int mid = (l + r + 1) >> 1;
282
+ long long sub = hashing.query(i + 1, i + mid);
283
+ if (s[mid].count(sub)) {
284
+ l = mid;
285
+ } else {
286
+ r = mid - 1;
287
+ }
288
+ }
289
+ return l;
290
+ };
291
+
292
+ int ans = 0, last = 0, mx = 0;
293
+ for (int i = 0; i < n; i++) {
294
+ int dist = f(i);
295
+ mx = max(mx, i + dist);
296
+ if (i == last) {
297
+ if (i == mx) {
298
+ return -1;
299
+ }
300
+ last = mx;
301
+ ans++;
302
+ }
303
+ }
304
+ return ans;
305
+ }
306
+ };
118
307
```
119
308
120
309
#### Go
121
310
122
311
``` go
123
-
312
+ type Hashing struct {
313
+ p []int64
314
+ h []int64
315
+ mod int64
316
+ }
317
+
318
+ func NewHashing (word string , base int64 , mod int64 ) *Hashing {
319
+ n := len (word)
320
+ p := make ([]int64 , n+1 )
321
+ h := make ([]int64 , n+1 )
322
+ p[0 ] = 1
323
+ for i := 1 ; i <= n; i++ {
324
+ p[i] = (p[i-1 ] * base) % mod
325
+ h[i] = (h[i-1 ]*base + int64 (word[i-1 ])) % mod
326
+ }
327
+ return &Hashing{p, h, mod}
328
+ }
329
+
330
+ func (hashing *Hashing ) Query (l , r int ) int64 {
331
+ return (hashing.h [r] - hashing.h [l-1 ]*hashing.p [r-l+1 ]%hashing.mod + hashing.mod ) % hashing.mod
332
+ }
333
+
334
+ func minValidStrings (words []string , target string ) (ans int ) {
335
+ base , mod := int64 (13331 ), int64 (998244353 )
336
+ hashing := NewHashing (target, base, mod)
337
+
338
+ m , n := 0 , len (target)
339
+ for _ , w := range words {
340
+ m = max (m, len (w))
341
+ }
342
+
343
+ s := make ([]map [int64 ]bool , m+1 )
344
+
345
+ f := func (i int ) int {
346
+ l , r := 0 , int (math.Min (float64 (n-i), float64 (m)))
347
+ for l < r {
348
+ mid := (l + r + 1 ) >> 1
349
+ sub := hashing.Query (i+1 , i+mid)
350
+ if s[mid][sub] {
351
+ l = mid
352
+ } else {
353
+ r = mid - 1
354
+ }
355
+ }
356
+ return l
357
+ }
358
+
359
+ for _ , w := range words {
360
+ h := int64 (0 )
361
+ for j := 0 ; j < len (w); j++ {
362
+ h = (h*base + int64 (w[j])) % mod
363
+ if s[j+1 ] == nil {
364
+ s[j+1 ] = make (map [int64 ]bool )
365
+ }
366
+ s[j+1 ][h] = true
367
+ }
368
+ }
369
+
370
+ var last , mx int
371
+
372
+ for i := 0 ; i < n; i++ {
373
+ dist := f (i)
374
+ mx = max (mx, i+dist)
375
+ if i == last {
376
+ if i == mx {
377
+ return -1
378
+ }
379
+ last = mx
380
+ ans++
381
+ }
382
+ }
383
+ return ans
384
+ }
124
385
```
125
386
126
387
<!-- tabs:end -->
0 commit comments