题目:
传送门
题意:给你一个p模式串,根据1、2两条规则变形,然后在s串中找符合p模式串的位置。
题解:bitset就相当于一个bool类型的数组,但是它可以方便的进行位运算,比如int类型最多进行32位的位运算,bitset可以进行任意位的位运算,具体资料以及各种操作的复杂度可以百度。然后讲讲dp部分,dp[now][i]存的是now位置i状态下满足条件的位置。另外开一个bitset数组a[26]用来记录每种字母在s串中出现的位置。从上一个位置转移到下一个位置如下图:
一共三种状态:0–与前面位置交换;1–不交换;2–与后面位置交换(根据题意p串只能前后交换且同一个字符不会交换多次)。状态转移如下图:
题意:给你一个p模式串,根据1、2两条规则变形,然后在s串中找符合p模式串的位置。
题解:bitset就相当于一个bool类型的数组,但是它可以方便的进行位运算,比如int类型最多进行32位的位运算,bitset可以进行任意位的位运算,具体资料以及各种操作的复杂度可以百度。然后讲讲dp部分,dp[now][i]存的是now位置i状态下满足条件的位置。另外开一个bitset数组a[26]用来记录每种字母在s串中出现的位置。从上一个位置转移到下一个位置如下图:

一共三种状态:0–与前面位置交换;1–不交换;2–与后面位置交换(根据题意p串只能前后交换且同一个字符不会交换多次)。状态转移如下图:
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PDD pair<double,double>
#define PLL pair<LL,LL>
#define MP(a,b) make_pair(a,b)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define MAXLL 0x3f3f3f3f3f3f3f3f
#define N 100005
#define EPS 1e-12
#define PI acos(-1.0)
#define MAX_SIZE 1100005
#define pb push_back
#define IN freopen("squary.in","r",stdin)
#define OUT freopen("squary.out","w",stdout)
#define fi first
#define se second
bitset<N> dp[2][3], a[26];
int n, m;
char s[N], p[5005];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
scanf("%s%s", s, p);
for(int i = 0; i < 26; i++)
a[i].reset();
for(int i = 0; i < n; i++)
a[s[i] - 'a'][i] = 1;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 3; j++)
dp[i][j].reset();
dp[0][1] = a[p[0] - 'a'];
if(m > 1)
dp[0][2] = a[p[1] - 'a'];
int now = 0, pre = 1;
for(int i = 1; i < m; i++)
{
pre = now;
now ^= 1;
dp[now][0] = dp[pre][2] & (a[p[i - 1] - 'a'] >> i);
dp[now][1] = (dp[pre][1] | dp[pre][0]) & (a[p[i] - 'a'] >> i);
if(i + 1 < m)
dp[now][2] = (dp[pre][1] | dp[pre][0]) & (a[p[i + 1] - 'a'] >> i);
}
for(int i = 0; i < n; i++)
{
if(dp[now][0][i] || dp[now][1][i])
printf("1");
else
printf("0");
}
puts("");
}
}