• Codeforces-914F Substrings in a String (Bitset求T串中S串出现次数)


    之前有过区域赛,简化版问题:

    给定一个小写字符组成的字符串S,(|S|<1e5,下标从1开始),现在有Q种操作,对于每个操作Q(Q<=1e5),输入opt,

    如果opt==1,输入x,c,表示把S[x]改为c,(c是小写字母)。

    如果opt==2,输入L,R,和字符串T,输出S[L-R]中有多少个字串==T(字符串可以重叠),(|T|<=100)。

    (其中opt==2的询问次数小于1e3)

    -------------------------------------------分界线-------------------------------------

    此题:

    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.

    Example

    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

    Note

    Consider the first sample case. Initially, the string aba occurs 3 times in the range [1, 7]. Note that two occurrences may overlap.

    After the update, the string becomes ababcbaba and now aba occurs only once in the range [1, 7].

    思路:题意和上面的差不多,不过数据更大一点,只有Bitset或者分块优化(后者我没有试过)。

    具体的:1,假设我们要统计S里有多少个T,先统计S里面字符==T[0]的是哪些,然后统计S中有T[0]的位置后面跟的字符==T[1]的有哪些,然后统计S中有T[0]的位置后面跟的字符==T[1]的而且后面跟的字符==T[2]的有哪些.....直到对比到S[len-1]。    

                  2,最后利用位移可以得到某个区间的1的个数。

    for(i=0;i<S;i++)
       ans&=(bitset[T[i]-'a']>>i);

    ans开始全部是1; bitset是保存的T串里每个字符的位置;

     (目测还有非常高效的方法,提交列表里有效率为5倍以上的,还有待学习)

    #include<bitset>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=100010;
    bitset<maxn>s[27],ans;
    char a[maxn],b[maxn],c[3];
    void read(int &res)
    {
        char c=getchar();
        while(c>'9'||c<'0') c=getchar();
        for(res=0;c>='0'&&c<='9';c=getchar()) res=(res<<3)+(res<<1)+c-'0';
    }
    int main()
    {
        scanf("%s",a+1);
        int T=strlen(a+1);
        int i,j,l,r,Q,opt;
        for(i=1;i<=T;i++)
            s[a[i]-'a'].set(i);
        read(Q);
        while(Q--){
            read(opt);
            if(opt==1){
                scanf("%d%s",&j,c);
                s[a[j]-'a'][j]=0;
                s[(a[j]=c[0])-'a'][j]=1;
            }
            else {
                read(l); read(r);
                scanf("%s",b);
                int S=strlen(b);
                if(S>r-l+1) {
                     puts("0"); continue;
                }
                ans.set();
                for(i=0;i<S;i++){
                    ans&=(s[b[i]-'a']>>i);
                }
                printf("%d
    ",(ans>>l).count()-(ans>>(r-S+2)).count());
            }
        }
        return 0;
    }
  • 相关阅读:
    (八)CXF之用spring添加拦截器
    (七)CXF之与spring整合发布web服务
    (六)CXF之自定义拦截器
    借鉴mini2440的usb-wifi工具集在Beagleboard上移植无线网卡
    ubuntu设置网络
    mysql优化学习
    java日期转化
    Navicat使用
    (转载)windows下mysql忘记密码
    java读取文件乱码
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8542239.html
Copyright © 2020-2023  润新知