扩展kmp
来源:互联网 发布:怎么盗用淘宝视频 编辑:程序博客网 时间:2024/05/22 08:07
给出两个字符串s1,s2,求出s2的每一个后缀在s1中出现的次数乘以这个后缀的长度,并累加求和,输出这个和
//next[i]表示pat与pat[i,len-1]的最长公共前缀//extend[i]表示pat与ori[i,len-1]的最长公共前缀typedef long long ll;const int N = 1000000 + 10, mod = 1e9 + 7;char ori[N], pat[N];int Next[N], extend[N];int num[N];int cas = 0;void get_next(char *pat){ int len = strlen(pat); Next[0] = len; int k = 0; while(k + 1 < len && pat[k] == pat[k+1]) ++k; Next[1] = k; k = 1; for(int i = 2; pat[i]; i++) { if(i + Next[i-k] < k + Next[k]) Next[i] = Next[i-k]; else { int j = max(k + Next[k] - i, 0); while(i + j < len && pat[j] == pat[i+j]) ++j; Next[i] = j; k = i; } }}void extkmp(char *ori, char *pat){ get_next(pat); int leno = strlen(ori), lenp = strlen(pat); int k = 0; while(k < leno && k < lenp && ori[k] == pat[k]) ++k; extend[0] = k; k = 0; for(int i = 1; ori[i]; i++) { if(i + Next[i-k] < k + extend[k]) extend[i] = Next[i-k]; else { int j = max(k + extend[k] - i, 0); while(i + j < leno && j < lenp && ori[i+j] == pat[j]) ++j; extend[i] = j; k = i; } }}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%s%s", ori, pat); int leno = strlen(ori), lenp = strlen(pat); reverse(ori, ori + leno); reverse(pat, pat + lenp); extkmp(ori, pat); memset(num, 0, sizeof num); for(int i = 0; i < leno; i++) num[extend[i]]++; ll ans = 0; for(int i = lenp; i >= 1; i--) { num[i] += num[i+1]; ans = (ans + 1LL * num[i] * i) % mod; } printf("%lld\n", ans); } return 0;}
阅读全文
0 0
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展 KMP
- 扩展kmp
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- *扩展KMP
- 扩展kmp
- DP训练 Codeforces 816E Karen And SuperMarket [树形DP]
- 关于S参数的一些理解
- [NOIP模拟]豆豆游戏
- 编写一个程序,将两个字符串s1和s2比较,如果s1 > s2,输出一个正数;s1 = s2,输出0,;s1 < s2输出一个负数。不要使用strcmp函数。
- hdu 3488 Tour (有向环最小权值覆盖,费用流)
- 扩展kmp
- opencv基础
- Linux常用命令集
- Linux——ssh
- mysql性能影响因素及基本配置
- OSG 节点访问器(NodeVisitor)
- 滚动数组
- 基本功
- java多态实现原理