题解UVA10298 Power Strings

· · 个人记录

UVA10298 Power Strings题解

前置芝士:hash 的熟练操作

题意:

求串 A 最多是由几个子串 B 组成

思路:

明显我们可以一个个枚举,然后判断当前长度为 kB 串是否拼的成

即判断 s[i + k - 1] - s[i - 1] * power[k] 是否等于 k

其中 s 即为 hash 数组,power_i 即为 base^i

由于本人是萌新

所以解释下为什么 * power[k]

很简单

举个栗子吧 ``` len = 6, k = 2, i = 3 ``` 那么我们来看看 ``` s[i + k - 1] = s[4] 即为 s[1] * base ^ 3 + s[2] * base ^ 2 + s[3] * base + s[4] ``` ``` s[i - 1] * power[k] = s[2] * power[2] 即为 (s[1] * base + s[2]) * base ^ 2 分配律一下 s[1] * base ^ 3 + s[2] * base ^ 2 ``` 两个相减 即为 ``` s[3] * base + s[4] ``` 那么我们目标不就是这个会等于 $B$ 串吗 很简单易懂吧 ## 代码: # CODE ```cpp #include <iostream> #include <cstring> #include <cstdio> #define ull unsigned long long const int N = 1e6 + 7; const ull base = 233; using namespace std; ull ha[N], power[N]; char s[N]; int len; inline bool check(ull x, int l) { for (int i = 1; i <= len; i += l) { if (x != ha[i + l - 1] - ha[i - 1] * power[l]) return 0; } return 1; } int main() { power[0] = 1; for (int i = 1; i <= N - 7; i ++) power[i] = power[i - 1] * base; while (1) { scanf("%s", s +1); if (s[1] == '.') return 0; len = strlen(s + 1); ha[0] = 0; for (int i = 1; i <= len; i ++) ha[i] = ha[i - 1] * base + (ull)(s[i]); for (int i = 1; i <= len; i ++) { if (len % i) continue; if (check(ha[i], i)) { cout << len / i << endl; break; } } } } ``` $Good$ $night