@@ -102,25 +102,286 @@ tags:
102102#### Python3
103103
104104``` 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
106153```
107154
108155#### Java
109156
110157``` 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+ }
112230```
113231
114232#### C++
115233
116234``` 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+ };
118307```
119308
120309#### Go
121310
122311``` 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+ }
124385```
125386
126387<!-- tabs:end -->
0 commit comments