1. 程式人生 > >『HDU 5716』帶可選字符的多字符串匹配 (bitset壓位)

『HDU 5716』帶可選字符的多字符串匹配 (bitset壓位)

pac getch urn 計算 blank review tom 這一 。。

傳送門戳這裏(●‘?‘●)

題目描述

有一個文本串,它的長度為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\n",i-n+1); 33 } 34 } 35 if(!flag){ 36 printf("NULL\n"); 37 } 38 getchar(); 39 } 40 return 0; 41 }

『HDU 5716』帶可選字符的多字符串匹配 (bitset壓位)