zoukankan      html  css  js  c++  java
  • CF700E Cool Slogans

    Link
    先建出SAM并维护每个endpos集合中元素的最后出现位置(pos)
    那么对于一个点(p),若(link_p)的endpos集合中有元素在([pos_p-len_p+len_{link_p},pos_p-1])中出现,那么说明(link_p)中的元素必在(p)的元素中出现至少两次。
    那么利用线段树合并维护出现位置,然后从上往下dp即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int N=400007,M=N*25;
    int cnt=1,now=1,tot,ch[N][26],len[N],link[N],a[N],top[N],pos[N],f[N],root[N],ls[M],rs[M];char str[N];
    void extend(int c)
    {
        int p=now,q;now=++cnt,pos[now]=len[now]=len[p]+1;
        for(;p&&!ch[p][c];p=link[p]) ch[p][c]=now;
        if(!p) return link[now]=1,void();
        if(len[q=ch[p][c]]==len[p]+1) return link[now]=q,void();
        link[++cnt]=link[q],memcpy(ch[cnt],ch[q],sizeof ch[q]),len[cnt]=len[p]+1,link[now]=link[q]=cnt,pos[cnt]=pos[q];
        for(;ch[p][c]==q;p=link[p]) ch[p][c]=cnt;
    }
    #define mid ((l+r)>>1)
    void update(int&p,int l,int r,int x)
    {
        if(p=++tot,l==r) return ;
        x<=mid? update(ls[p],l,mid,x):update(rs[p],mid+1,r,x);
    }
    int merge(int u,int v)
    {
        if(!u||!v) return u|v; int t=++tot;
        return ls[t]=merge(ls[u],ls[v]),rs[t]=merge(rs[u],rs[v]),t;
    }
    int query(int p,int l,int r,int L,int R){return p&&((L<=l&&r<=R)||((L<=mid&&query(ls[p],l,mid,L,R))||(R>mid&&query(rs[p],mid+1,r,L,R))));}
    #undef mid
    void sort()
    {
        static int c[N];
        for(int i=1;i<=cnt;++i) ++c[len[i]];
        for(int i=1;i<=cnt;++i) c[i]+=c[i-1];
        for(int i=1;i<=cnt;++i) a[c[len[i]]--]=i;
    }
    int main()
    {
        int n,ans=1;
        scanf("%d%s",&n,str+1);
        for(int i=1;i<=n;++i) extend(str[i]-'a'),update(root[now],1,n,i);
        sort();
        for(int i=cnt;i^1;--i) root[link[a[i]]]=merge(root[link[a[i]]],root[a[i]]);
        for(int i=2,u,p,x;i<=cnt;++i)
    	if((p=link[u=a[i]])==1) f[u]=1,top[u]=u;
            else query(root[top[p]],1,n,pos[u]-len[u]+len[top[p]],pos[u]-1)? (f[u]=f[p]+1,top[u]=u):(f[u]=f[p],top[u]=top[p]),ans=std::max(ans,f[u]);
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    Python运算符,基本数据类型
    Python2 错误记录1File "<string>", line 1, in <module> NameError: name 'f' is not defined
    用户登录三次练习
    跟我一起学Python-day1(条件语句以及初识变量)
    vim operation
    步步为营-28-事件本质
    步步为营-27-事件
    步步为营-26-多播委托
    步步为营-25-委托(比大小)
    步步为营-24-委托
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12489052.html
Copyright © 2011-2022 走看看