Shift - And字符串快速處理 hdu5972+cf
基礎知識介紹
KMP就是不斷往前找1的位置,而ShiftAnd經過三步處理已經完成這個叠代的過程了
如果匹配兩個字符集有限的字符串的話,那麽Shift-And比kmp要快,找區間內某字符串出現的數目也可以只與這個字符串的長度有關。。
Regular Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1650 Accepted Submission(s): 450
Problem Description Using regular expression to define a numeric string is a very common thing. Generally, use the shape as follows:
(0|9|7) (5|6) (2) (4|5)
Above regular expression matches 4 digits:The first is one of 0,9 and 7. The second is one of 5 and 6. The third is 2. And the fourth is one of 4 and 5. The above regular expression can be successfully matched to 0525, but it cannot be matched to 9634.
Now,giving you a regular expression like the above formula,and a long string of numbers,please find out all the substrings of this long string that can be matched to the regular expression.
Input It contains a set of test data.The first line is a positive integer N (1 ≤ N ≤ 1000),on behalf of the regular representation of the N bit string.In the next N lines,the first integer of the i-th line is ai
Output Output all substrings that can be matched by the regular expression. Each substring occupies one line
Sample Input 4 3 0 9 7 2 5 7 2 2 5 2 4 5 09755420524
Sample Output 9755 7554 0524
Source 2016ACM/ICPC亞洲區大連站-重現賽(感謝大連海事大學)
#include<cstdio> #include<bitset> #include<algorithm> using namespace std; bitset<1008>M[10],S; char s[5000008]; int main(){ int n,t,x; while(scanf("%d",&n)!=EOF){ for(int i=0;i<10;++i) M[i].reset(); S.reset(); for(int i=1;i<=n;++i) { for(scanf("%d",&t);t--;){ scanf("%d",&x); M[x].set(i); } } scanf("%s",s); for(int i=0;s[i];++i) { S<<=1; S.set(1); S&=M[s[i]-‘0‘]; if(S[n]==1) { char tmp=s[i+1]; s[i+1]=0; puts(s+i-n+1); s[i+1]=tmp; } } } }
F. Substrings in a String time limit per test 6 seconds memory limit per test 256 megabytes input standard input output standard output
Given a string s, process q queries, each having one of the following forms:
- 1?i?c — Change the i-th character in the string to c.
- 2?l?r?y — Consider the substring of s starting at position l and ending at position r. Output the number of times y occurs as a substring in it.
The first line of the input contains the string s (1?≤?|s|?≤?105) of lowercase English letters.
The second line contains an integer q (1?≤?q?≤?105) — the number of queries to process.
The next q lines describe the queries and may have one of the following forms:
- 1?i?c (1?≤?i?≤?|s|)
- 2?l?r?y (1?≤?l?≤?r?≤?|s|)
c is a lowercase English letter and y is a non-empty string consisting of only lowercase English letters.
The sum of |y| over all queries of second type is at most 105.
It is guaranteed that there is at least one query of second type.
All strings are 1-indexed.
|s| is the length of the string s.
OutputFor each query of type 2, output the required answer in a separate line.
Examples InputababababaOutput
3
2 1 7 aba
1 5 c
2 1 7 aba
3Input
1
abcdcbcOutput
5
2 1 7 bc
1 4 b
2 4 7 bc
1 2 a
2 1 4 aa
2
2
1
轉載
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #include<bitset> #define ll long long using namespace std; const int maxn=100010, inf=1e9; int n, ty, l, r, x; bitset<maxn>v[26], ans; char s[maxn], s2[maxn], c; inline void read(int &k) { int f=1; k=0; char c=getchar(); while(c<‘0‘ || c>‘9‘) c==‘-‘&&(f=-1), c=getchar(); while(c<=‘9‘ && c>=‘0‘) k=k*10+c-‘0‘, c=getchar(); k*=f; } 1 int main() { scanf("%s", s+1); int len=strlen(s+1); for(int i=1;i<=len;i++) v[s[i]-‘a‘][i]=1; read(n); for(int i=1;i<=n;i++) { read(ty); if(ty==1) { read(x); scanf("%c", &c); v[s[x]-‘a‘][x]=0; v[(s[x]=c)-‘a‘][x]=1; } else { read(l); read(r); scanf("%s", s2); int m=strlen(s2); if(r-l+1<m) {puts("0"); continue;} ans.set(); for(int j=0;j<m;j++) ans&=(v[s2[j]-‘a‘]>>j); printf("%d\n", (int)(ans>>(l)).count()-(int)(ans>>(r-m+2)).count()); } } }
Shift - And字符串快速處理 hdu5972+cf