ZOJ 3587 Marlon's String 扩展KMP
来源:互联网 发布:淘宝上的冷门刚需产品 编辑:程序博客网 时间:2024/05/22 06:53
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3587
题意:给出两个字符串S和T,S,T<=100000.拿出S的两个子串(可以重叠),将两个子串连接起来成为字符串T的方法有多少种。
思路:用扩展KMP求出S的从每位开始的子串与T的公共前缀,再将两个子串翻转,再用扩展KMP求出S反的从每位开始的子串与T反的公共前缀。找出其中和为T子串长度的S公共前缀和S反的公共前缀的数量,相乘为结果。
代码:
#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define eps 1e-8#define INF 0x7fffffff#define maxn 10005#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;const int N = 101010;int next_a[N],extand_a[N],next_c[N],extand_c[N];void getnext(char *T,int *next,int *extand) // next[i]: 以第i位置开始的子串 与 T的公共前缀{ int i,length = strlen(T); next[0] = length; for(i = 0; i<length-1 && T[i]==T[i+1]; i++); next[1] = i; int a = 1; for(int k = 2; k < length; k++) { int p = a+next[a]-1, L = next[k-a]; if( (k-1)+L >= p ) { int j = (p-k+1)>0? (p-k+1) : 0; while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 next[k] = j, a = k; } else next[k] = L; }}void getextand(char *S,char *T,int *next,int *extand) //s是母串,t是模式串{ memset(next,0,sizeof(next)); getnext(T,next,extand); int Slen = strlen(S), Tlen = strlen(T), a = 0; int MinLen = Slen>Tlen?Tlen:Slen; while(a<MinLen && S[a]==T[a]) a++; extand[0] = a, a = 0; for(int k = 1; k < Slen; k++) { int p = a+extand[a]-1, L = next[k-a]; if( (k-1)+L >= p ) { int j = (p-k+1)>0? (p-k+1) : 0; while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++; extand[k] = j; a = k; } else extand[k] = L; }}char a[100005],b[100005],c[100005],d[100005];LL t_a[100005],t_c[100005];void init(){ memset(t_a,0,sizeof(t_a)); memset(t_c,0,sizeof(t_c));}int main(){ //freopen("1.txt","r",stdin); int T; scanf("%d",&T); while(T--) { init(); scanf("%s",a); scanf("%s",b); int len_a=strlen(a); for(int i=0;i<len_a;i++) c[i]=a[len_a-1-i]; c[len_a]='\0'; int len_b=strlen(b); for(int i=0;i<len_b;i++) d[i]=b[len_b-1-i]; d[len_b]='\0'; getextand(a,b,next_a,extand_a); getextand(c,d,next_c,extand_c); for(int i=0;i<len_a;i++) { t_a[extand_a[i]]++; t_c[extand_c[i]]++; } for(int i=len_a-1;i>=1;i--) { t_a[i]+=t_a[i+1]; t_c[i]+=t_c[i+1]; } LL ans=0; for(int i=1;i<len_b;i++) { ans+=t_a[i]*t_c[len_b-i]; } printf("%lld\n",ans); } return 0;}
2 1
- ZOJ 3587 Marlon's String 扩展KMP
- 【KMP】ZOJ-3587-Marlon's String
- [zoj 3587]Marlon's String[kmp]
- zoj 3587 Marlon's String(拓展KMP+dp)
- ZOJ 题目3587 Marlon's String(KMP)
- zoj 3587 Marlon's String
- ZOJ 3587 Marlon's String
- KMP:Marlon's String
- Zoj 3587 Marlon's String (KMP 字符串拼接 前缀出现次数)
- ZOJ3587 Marlon's String KMP技巧处理
- zoj3587 Marlon's String(next 数组和kmp)
- zoj2587 Marlon's String
- ZOJ3587 Marlon's String
- Marlon's String zoj3587
- ZOJ 3587 扩展KMP
- ZOJ 3587 扩展KMP应用
- 【ZOJ3587】Marlon's String——白四爷×KMP 白濑肆の算法完全解读KMP篇 KMP来袭第二弹前缀什么的果然最讨厌了!【1.0%达成!】
- HDOJ4300Clairewd’s message【扩展KMP】
- 【视频】嵌入式Linux/Android驱动开发揭秘(4)重力传感器驱动开发
- LevelDB源码剖析之Memtable(2)
- zhifubao外链开发库
- backbone.js 初探
- mysql存储过程实例
- ZOJ 3587 Marlon's String 扩展KMP
- 我翻过的Android图书
- jsp调用ocx
- 动态规划
- Oracle会话及连接数优化
- FreeSWITCH ESL (Event Socket Library)
- USB协议栈设备框架和连接枚举过程
- 嵌入式linux的网络编程(1)--TCP/IP协议概述
- python调用dll