『HDU 5716』帶可選字符的多字符串匹配 (bitset壓位)
阿新 • • 發佈:2018-08-19
pac getch urn 計算 blank review tom 這一 。。
傳送門戳這裏(●‘?‘●)
題目描述
有一個文本串,它的長度為m(1≤m≤2000000),現在想找出其中所有的符合特定模式的子串位置。
符合特定模式是指,該子串的長度為n(1≤n≤500),並且第i個字符需要在給定的字符集合Si中。
因此,描述這一特定模式,共需要S1,S2,...,Sn這n個字符集合。每個集合的大小都在1∼62之間,其中的字符只為數字或大小寫字母。
解題思路
考場上暴力倒著匹配居然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壓位)