zoukankan      html  css  js  c++  java
  • HDU4641 K-string(后缀自动机)

    Problem Description
    Given a string S. K-string is the sub-string of S and it appear in the S at least K times.It means there are at least K different pairs (i,j) so that Si,Si+1... Sj equal to this K-string. Given m operator or query:1.add a letter to the end of S; 2.query how many different K-string currently.For each query ,count the number of different K-string currently.
     
    Input
    The input consists of multiple test cases. 
    Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S.
    The second line consists string S,which only contains lowercase letters. 
    The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
     
    Output
    For each query print an integer — the number of different K-string currently.
     
    Sample Input
    3 5 2
    abc
    2
    1 a
    2
    1 a
    2
     
     
    Sample Output
    0
    1
    1
     

     关键词:在线处理;不需要topsort;避免重复。

    合理剪枝,只处理maxlen-minlen+1==k的情况,>k不作考虑,如果和上一道题一样记录used就会超时。

       

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<string>
    using namespace std;
    const int maxn=300100;
    int tot,slink[2*maxn],trans[2*maxn][26],maxlen[2*maxn];
    char str[maxn];
    int N,M,K,num[2*maxn],last;
    long long ans;
    void init()
    {
        ans=tot=0;
        last=0;
        memset(trans[0],-1,sizeof(trans[0]));
        slink[0]=-1; maxlen[0]=0;
    }
    void add_char(char chr) 
    {
        int c=chr-'a';
        int p=last,np=++tot;
        maxlen[np]=maxlen[p]+1;
        memset(trans[np],-1,sizeof(trans[np])); 
        num[np]=0;
        while(p!=-1&&trans[p][c]==-1)  trans[p][c]=np,p=slink[p];
        if(p==-1) slink[np]=0;
        else
        {
            int q=trans[p][c];
            if(maxlen[q]!=maxlen[p]+1)
            {
                int nq=++tot;
                memcpy(trans[nq],trans[q],sizeof(trans[q])); num[nq]=num[q];
                maxlen[nq]=maxlen[p]+1;
                slink[nq]=slink[q];
                slink[np]=slink[q]=nq;
                while(p!=-1&&trans[p][c]==q) trans[p][c]=nq,p=slink[p];
            }
            else slink[np]=q;
        }
        last=np;
        while(np!=-1&&num[np]<K) //没有达到K次的就加1
        {
            num[np]++;
            if(num[np]>=K) ans+=maxlen[np]-maxlen[slink[np]]; //加上答案
            np=slink[np];
        }
    }
    int main() {
        while(~scanf("%d%d%d",&N,&M,&K)){ 
           char c[2];
           init();
           scanf("%s",str);
           for(int i=0; i<N; i++)   add_char(str[i]);
           for(int i=1;i<=M;i++){
                int tmp;
                scanf("%d",&tmp);
                if(tmp==2) printf("%lld
    ",ans);
                else {
                    scanf("%s",c);
                    add_char(c[0]);
               }
           }
        }
        return 0;
    }
  • 相关阅读:
    CSS 背景
    CSS padding 属性
    CSS border 属性和 border-collapse 属性
    CSS margin 属性
    IEnumerable<T> 接口和GetEnumerator 详解
    discuz! X3.4特殊字符乱码解决方案
    Discuz通过修改文章标题更好的实现SEO的方法
    关于Discuz x3.3页面空白解决方法
    discuz x3.3标题的最少字数限制设置方法
    discuz网站前端代码优化思路
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7894923.html
Copyright © 2011-2022 走看看