[JZOJ 3427] 归途与征程
2016-06-01 12:41
288 查看
Description
对于100%的测试点,1<=N<=100,1<=M<=100000。
Analysis
我们可以把A串视为一些串中间隔着一些星号。显然,A串头尾都没有星号是有星号的特殊情况。因为无星号可以跳过头尾的串变成头尾都是星号。
下图,上者A,下者B。
我们可以对于A串中的小串与B串做一次KMP,搞一个bz[i][j]表示第i个小串是否能与B的第j个位置往后相应长度匹配。再搞一个f[i][j]表示第j个位置及其右边的第一个能与A串的i小串相匹配的位置。这样一直跳,跳,跳即可。时间复杂度是O(nm)的。
Code
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,b,a) for(int i=b;i>=a;i--) using namespace std; const int N=110,M=200010; int n,m,len,num,next ,f [M],c ; char a ,b[M],s ; bool p1,pn,bz [M]; void kmp(int st) { int j=0; fo(i,2,n) { while(j && s[i]!=s[j+1]) j=next[j]; next[i]=s[i]==s[j+1]?(++j):(j=0); } j=0; fo(i,2,m*2) { while(j && b[i]!=s[j+1]) j=next[j]; if(b[i]==s[j+1]) j++; if(j==c[st]) bz[st][i-j+1]=1; } f[st][m*2+1]=m*2+1; fd(j,m*2,1) if(bz[st][j]) f[st][j]=j; else f[st][j]=f[st][j+1]; } bool match(int x) { int y=x+m-1,l=1,r=num; if(!p1) { if(!bz[l][x]) return 0; x+=c[l++]; } if(!pn) { if(!bz[r][y-c[r]+1]) return 0; y-=c[r--]; } for(;l<=r;l++) { x=f[l][x]; if(x>y) return 0; x+=c[l]-1; } if(x>y) return 0; return 1; } int main() { scanf("%s\n%s",a+1,b+1); n=strlen(a+1),m=strlen(b+1); p1=a[1]=='*',pn=a =='*'; fo(i,m+1,m*2) b[i]=b[i-m]; int i=0; while(++i<=n) { int len=0; for(;i<=n && a[i]!='*';i++) s[++len]=a[i]; if(!len) continue; c[++num]=len; kmp(num); } int ans=0; fo(i,1,m) if(match(i)) ans++; printf("%d",ans); return 0; }
相关文章推荐
- js动态函数和匿名函数
- Gradle配置keystore
- 资源管理器 C#文档 内涵资源链接
- 精通Objective-C 第一章~第三章读书笔记
- html绘制五角星。。
- 关于Linux网络程序的一些小问题
- win7虚拟无线工具+wifi下eclipse调试工具
- HTML5、formData移动浏览器上传图片
- Spring WebSocket 使用详解
- 程序设计大赛
- 提高Android studio流畅度
- Binary Tree Inorder Traversal
- MariaDB/MySQL Galera服务器的防火墙规则
- log4j.properties 的使用详解
- js计时器
- iOS控件之UIButton
- 五分钟搞懂Android的消息机制(Handle,Looper,MessageQueue)
- 交换排序之快速排序
- ACM专题三总结
- 如何部署 Hyperic ,使得从内网监测外网服务器