【JZOJ4624】字符串匹配
2016-07-14 08:35
393 查看
Description
Solution
诶,这题不是赤裸裸kmp吗?对于|S|<|T|的情况,直接做kmp,统计答案就行。
那对于普遍情况呢?
我们先复制T串使得|S|<|T|,记这时有k段T串,然后跑一次kmp,得出的答案记为a1,再复制一段T,跑一次kmp,得出的答案记为a2,那么我们很容易求出在此基础上每复制一段所增加的匹配数就为(a2−a1),总匹配数就为:a1+(a2−a1)(n−k)。
Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) #define N 100001 #define ll long long using namespace std; int f ; char s ,T[N*4]; int l1,l2,l3; void get() { int j=0; fo(i,2,strlen(s+1)) { while(j>0 && s[j+1]!=s[i]) j=f[j]; if (s[j+1]==s[i]) j++; f[i]=j; } } int kmp(int l,int r) { int j=0; int ans=0; fo(i,l,r) { while (j>0 && s[j+1]!=T[i]) j=f[j]; if (s[j+1]==T[i]) j++; if (j==l1) { ans++; j=f[j]; } } return ans; } int main() { freopen("4624.in","r",stdin); freopen("4624.out","w",stdout); ll n; cin>>n; cin>>s+1; cin>>T+1; get(); l1=strlen(s+1),l2=strlen(T+1),l3=l2; n--; while(l3<=l1 && n) { n--; fo(i,l3+1,l2+l3) T[i]=T[i-l2]; l3+=l2; } int t1=kmp(1,l3); fo(i,l3+1,l3+l2) T[i]=T[i-l3]; l3+=l2; int t2=kmp(1,l3); cout<<t1*1ll+(t2-t1)*1ll*n; }
相关文章推荐
- imx6设备树中断说明
- 关于PostgreSQL与MongoDB在NoSQL方面的简单对比
- 堆排序
- 安全观察:浅谈WAF几种常见的部署模式
- 【APIO2016】字符串匹配
- 5 个免费的项目管理工具推荐
- 图文混排
- python学习——多重继承
- 日夜间模式切换
- Ubuntu怎样安装无线网卡驱动解决无线网不能连接
- Tjoi2016&Heoi2016 求和
- 苹果iOS系统下的推送机制及实现
- Android 中文件类型与MIME的匹配表
- 求最长上升子序列
- 上拉刷新下拉加载xlistview_footer
- 匹配字符串-好技能-正则表达式
- Count 1 in Binary
- 上拉刷新下拉加载xlistview_header
- IOS atomic与nonatomic,assign,copy与retain的定义和区别
- 正则表达式匹配字符串