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(1ai10) ,representing that the i-th position of regular expression has ai numbers to be selected.Next there are ai numeric characters. In the last line,there is a numeric string.The length of the string is not more than 5 * 10^6.
 

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
 
#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 ic — Change the i-th character in the string to c.
  • 2 lry — 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.
Input

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 ic (1 ≤ i ≤ |s|)
  • 2 lry (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.

Output

For each query of type 2, output the required answer in a separate line.

Examples
Input
ababababa
3
2 1 7 aba
1 5 c
2 1 7 aba
Output
3
1
Input
abcdcbc
5
2 1 7 bc
1 4 b
2 4 7 bc
1 2 a
2 1 4 aa
Output
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());
        }
    }
}

 

posted @ 2018-02-07 22:12  Billyshuai  阅读(246)  评论(0编辑  收藏  举报