『HDU 5716』带可选字符的多字符串匹配 (bitset压位)

Posted fang-hao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『HDU 5716』带可选字符的多字符串匹配 (bitset压位)相关的知识,希望对你有一定的参考价值。

传送门戳这里(●‘?‘●)

 

题目描述

有一个文本串,它的长度为m(1m2000000),现在想找出其中所有的符合特定模式的子串位置。
符合特定模式是指,该子串的长度为n(1n500),并且第i个字符需要在给定的字符集合Si中。
因此,描述这一特定模式,共需要S1,S2,...,Snn个字符集合。每个集合的大小都在162之间,其中的字符只为数字或大小写字母。

 

解题思路

 考场上暴力倒着匹配居然90分,≈正解(喵喵喵???)

提示是bitset优化,但是不会啊。。。。

于是照着网上的题解写了一份qwq

首先用w表示每个字符在那个串里出现过,用p表示能否匹配到二进制下的位,滚动数组计算。

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<bitset>
 6 using namespace std;
 7 const int maxn=2000050;
 8 const int maxm=512;
 9 int n,slen;
10 char s[maxn],ss[100];
11 bitset<maxm>w[300],p[2];
12 int main(){
13     while(gets(s+1)){
14         slen=strlen(s+1);
15         scanf("%d",&n);
16         for(register int i=0;i<300;i++)w[i].reset();
17         for(register int i=1,tmp;i<=n;i++){
18             scanf("%d",&tmp);
19             scanf("%s",ss+1);
20             for(register int j=1;j<=tmp;j++){
21                 w[ss[j]][i]=1;
22             }
23         }
24         int flag=0,now=0;
25         p[now].reset();
26         p[now][0]=1;
27         for(register int i=1;s[i];i++){
28             p[!now]=(p[now]<<1)&w[s[i]];
29             now^=1,p[now][0]=1;
30             if(p[now][n]){
31                 flag=1;
32                 printf("%d
",i-n+1);
33             }
34         }
35         if(!flag){
36             printf("NULL
");
37         }
38         getchar();
39     }
40     return 0;
41 }

 

以上是关于『HDU 5716』带可选字符的多字符串匹配 (bitset压位)的主要内容,如果未能解决你的问题,请参考以下文章

hdu5716

Laravel whereBetween 带可选参数

Laravel 5,子域路由,带可选参数

hdu5414(2015多校10)--CRB and String(字符串匹配)

HDU 6170 Two strings (DP)

hdu2203kmp匹配