Professor Zhang would like to solve the multiple pattern matching problem, but he only has only one pattern string
p=p1p2...pm
. So, he wants to generate as many as possible pattern strings from
p
using the following method:
1. select some indices i1,i2,...,ik such that 1≤i1<i2<...<ik<|p| and |ij−ij+1|>1 for all 1≤j<k .
2. swap pij and pij+1 for all 1≤j≤k .
Now, for a given a string s=s1s2...sn , Professor Zhang wants to find all occurrences of all the generated patterns in s .
1. select some indices i1,i2,...,ik such that 1≤i1<i2<...<ik<|p| and |ij−ij+1|>1 for all 1≤j<k .
2. swap pij and pij+1 for all 1≤j≤k .
Now, for a given a string s=s1s2...sn , Professor Zhang wants to find all occurrences of all the generated patterns in s .
The first line contains two integers n and m (1≤n≤105,1≤m≤min{5000,n}) -- the length of s and p .
The second line contains the string s and the third line contains the string p . Both the strings consist of only lowercase English letters.
3 4 1 abac a 4 2 aaaa aa 9 3 abcbacacb abc
1010 1110100100100
- 这道题定义f[i][j][k]表示——
- a串匹配到位点a[i]
- b串匹配到位点b[j]
- j这个位置的匹配状态为k(0表示b[j]要与b[j-1]交换,1表示没有交换,2表示b[j+1]交换)
- 转移方程是这个样子的——
- dp[i][j][0]=dp[i-1][j-1][2] & (a[i]==b[j-1])
- //a[i-1]与b[0~j-1]匹配了,且a[i]实际要与b[j-1]做匹配
- dp[i][j][1]=dp[i-1][j-1][0] & (a[i]==b[j])
- |dp[i-1][j-1][1] & (a[i]==b[j])
- //a[i-1]与b[0~j-1]匹配了,且a[i]实际要与b[j]做匹配
- dp[i][j][2]=dp[i-1][j-1][0] & (a[i]==b[j+1])
- |dp[i-1][j-1][1] & (a[i]==b[j+1])
- //a[i-1]与b[0~j-1]匹配了,且a[i]实际要与b[j+1]做匹配
ac代码:
#include <bits/stdc++.h> using namespace std; const int N=1e5+7; int n,m; char a[N],b[5007],ans[N]; bitset<N>dp[3],num[26]; int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%s%s",&n,&m,a+1,b+1); for(int i=0;i<=25;i++) num[i].reset(); for(int i=1;i<=n;i++) num[a[i]-'a'][i]=1; for(int i=0;i<=2;i++) dp[i].reset(); dp[0].set(); for(int i=1;i<=m;i++) { int x=b[i]-'a',y=b[i-1]-'a',z=b[i+1]-'a'; dp[0]=((dp[0]|dp[1])<<1); if(i>1) dp[1]=(dp[2]<<1)&num[y]; if(i<m) dp[2]=dp[0]&num[z]; dp[0]&=num[x]; } for(int i=m;i<=n;i++) ans[i-m+1]='0'+(dp[0][i]|dp[1][i]); for(int i=n-m+2;i<=n;i++) ans[i]='0'; ans[n+1]=0; puts(ans+1); } }