1 条题解
-
0
#include <bits/stdc++.h> using namespace std; using ll = long long; // 使用 using 定义 long long 别名 const ll MOD = 1e9 + 7; int main() { int T; scanf("%d", &T); // 读取测试数据组数 while (T--) { char s[1000010]; // 存储输入的字符串 scanf("%s", s); int n = strlen(s); // 获取字符串长度 // 使用 vector 动态分配数组 vector<int> fail(n + 1); // next 数组(KMP 中的失配指针) vector<int> ans(n + 1); // 存储每个前缀的 border 数量 ll cnt = 1; // 最终结果,初始化为 1(乘法单位元) // 第一部分:计算 next 数组和 ans 数组 int j = 0; // 当前匹配长度 ans[0] = 0; // 空字符串没有 border ans[1] = 1; // 长度为 1 的前缀没有 border,但 ans[1] 设为 1(用于后续计算) // 遍历字符串,计算 next 数组 for (int i = 1; i < n; i++) { // KMP 的核心跳转逻辑:当字符不匹配时,跳转到上一个匹配位置 while (j && s[i] != s[j]) j = fail[j]; // 如果当前字符匹配,增加匹配长度 if (s[i] == s[j]) j++; fail[i + 1] = j; // 记录 next 值 ans[i + 1] = ans[j] + 1; // 递推计算 border 数量 } // 第二部分:计算 num 数组的乘积 j = 0; // 重置匹配长度 for (int i = 1; i < n; i++) { // 注意:从 1 开始,跳过单个字符的情况 // KMP 的核心跳转逻辑 while (j && s[i] != s[j]) j = fail[j]; // 如果当前字符匹配,增加匹配长度 if (s[i] == s[j]) j++; // 确保 border 不重叠:当前匹配长度不能超过一半 while (j * 2 > i + 1) j = fail[j]; // 累乘 (num[i+1] + 1),即 (ans[j] + 1) cnt = (cnt * (ans[j] + 1)) % MOD; } printf("%lld\n", cnt); // 输出结果 } return 0; }
- 1
信息
- ID
- 1382
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者