HDU6153 A Secret(扩展KMP)2017中国大学生程序设计竞赛
来源:互联网 发布:有哪些数据库管理系统 编辑:程序博客网 时间:2024/06/05 02:17
题意:给两个串s1和s2,对于s2的每个后缀,Li表示后缀的长度,Ni表示这个后缀在s1里面出现过的次数。求Ni * Li 的总和。
思路:后缀匹配,反过来就是前缀匹配了嘛!反转两个字符串做一次扩展KMP,遍历extend数组,如果一个位置的匹配长度是len,那么说明所有长度小于等于len的原串后缀匹配次数都增加了一次。求和输出即可。
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<vector>#include<map>#include<algorithm>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const int mod = 1000000007;const int maxn = 1000005;char s1[maxn], s2[maxn], s3[maxn], s4[maxn];int extend[maxn], nxt[maxn];int cnt[maxn];void get_next(char str[]){ int i = 0, j, pos; int len = strlen(str); nxt[0] = len; while(i + 1 < len && str[i] == str[i + 1]){ ++i; } nxt[1] = i; pos = 1; for(i=2; i<len; ++i){ if(nxt[i - pos] < pos + nxt[pos] - i){ nxt[i] = nxt[i - pos]; } else { j = nxt[pos] + pos - i; if(j < 0){ j = 0; } while(i + j < len && str[i + j] == str[j]){ ++j; } nxt[i] = j; pos = i; } }}void EXKMP(char target[], char pattern[]){ int i = 0, j, pos; get_next(pattern); int len1 = strlen(target); int len2 = strlen(pattern); while(i < len1 && i < len2 && target[i] == pattern[i]){ ++i; } extend[0] = i; pos = 0; for(i=1; i<len1; ++i){ if(nxt[i - pos] < pos + extend[pos] - i){ extend[i] = nxt[i - pos]; } else { j = extend[pos] + pos - i; if(j < 0){ j = 0;//从头匹配 } while(i + j < len1 && j < len2 && target[i + j] == pattern[j]){ ++j; } extend[i] = j; pos = i;//更新pos } }}int main(){ int t; scanf("%d", &t); while(t--){ scanf("%s%s", s1, s2); memset(cnt, 0, sizeof(cnt)); int l1 = strlen(s1); int l2 = strlen(s2); for(int i = 0; i < l1; ++i){ s4[i] = s1[l1 - 1 - i]; } s4[l1] = 0; for(int i = 0; i < l2; ++i){ s3[i] = s2[l2 - 1 - i]; } s3[l2] = 0; EXKMP(s4, s3); for(int i = 0; i < l1; ++i){ ++cnt[extend[i]];//cnt[i]记录长度i的后缀匹配次数 } ll ans = 0; for(ll i = 1; i <= (ll)l1; ++i){ if(cnt[i]){ ans = (ans + (i + 1) * i / 2 * (ll)cnt[i]) % mod;//所有长度小于i的后缀匹配次数都加一 } } printf("%lld\n", ans); }}
阅读全文
0 0
- HDU6153 A Secret(扩展KMP)2017中国大学生程序设计竞赛
- hdu6153-A Secret (kmp/扩展kmp)
- HDU6153 A Secret 扩展KMP
- 【HDU6153】A Secret(扩展KMP)
- [扩展kmp] hdu6153 A Secret
- 【HDU6153 2017中国大学生程序设计竞赛
- hdu6153(kmp) A Secret
- hdu6153(kmp) A Secret
- hdu6153 A Secret CCPC1004 扩展KMP
- [kmp] hdu6153 A Secret
- hdu6153 A Secret (拓展KMP)
- HDU-2017中国大学生程序设计竞赛-网络选拔赛-1004-A Secret
- HDU6153-A Secret ex-kmp
- HDU6153-A Secret
- HDU6153-A Secret
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 2017中国大学生程序设计竞赛
- 动态规划和贪心算法的比较
- 关于Java多线程的理解
- 一台电脑上的两台linux使用VMnet8模式实现互通(静态ip地址)
- Unity制作游戏在部分手机上显示黑白屏幕
- 面试题30:最小的K个数及topK问题的解决
- HDU6153 A Secret(扩展KMP)2017中国大学生程序设计竞赛
- POJ 2352 Stars
- jsp总结
- nyoj61传纸条(一) 双线DP
- 20170819考试总结
- Unity2--利用脚本打印图形
- java爬取下载文件
- 聊聊鹅厂及鹅厂出来的coder们的面试套路
- 【剑指offer】面试题 39:数组中出现次数超过一半的数字