zoukankan      html  css  js  c++  java
  • bzoj2865: 字符串识别(后缀自动机 + 线段树)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2865

    同上一篇博客

    就是卡卡空间,数组改成map

    #include<map>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    #define N 500001
     
    using namespace std;
     
    char s[N];
     
    map<int,int>ch[N<<1];
    int tot=1;
    
    int fa[N<<1],len[N<<1];
    int siz[N<<1]; 
    int last=1,p,q,np,nq;
     
    int leaf[N];
     
    int v[N],sa[N<<1];
     
    struct Segment
    {
        int mx[N<<2];
        int tag[N<<2];
     
        void down(int k)
        {
            mx[k<<1]=min(mx[k<<1],tag[k]);
            mx[k<<1|1]=min(mx[k<<1|1],tag[k]);
            tag[k<<1]=min(tag[k<<1],tag[k]);
            tag[k<<1|1]=min(tag[k<<1|1],tag[k]);
            tag[k]=2e9;
        }
     
        void build(int k,int l,int r)
        {
            mx[k]=tag[k]=2e9;
            if(l==r) return;
            int mid=l+r>>1;
            build(k<<1,l,mid);
            build(k<<1|1,mid+1,r);
        }
     
        void change(int k,int l,int r,int opl,int opr,int w)
        {
            if(l>=opl && r<=opr)
            {
                mx[k]=min(mx[k],w);
                tag[k]=min(tag[k],w);
                return;
            }
            int mid=l+r>>1;
            if(tag[k]!=2e9) down(k);
            if(opl<=mid) change(k<<1,l,mid,opl,opr,w);
            if(opr>mid) change(k<<1|1,mid+1,r,opl,opr,w);
            mx[k]=min(mx[k<<1],mx[k<<1|1]);
        }
     
        int query(int k,int l,int r,int x)
        {
            if(l==r) return mx[k];
            int mid=l+r>>1;
            if(tag[k]!=2e9) down(k);
            if(x<=mid) return query(k<<1,l,mid,x);
            return query(k<<1|1,mid+1,r,x);
        }
    };
     
    Segment tr1,tr2;
     
    void extend(int c)
    {
        len[np=++tot]=len[last]+1;
        siz[tot]=1;
        for(p=last;p && ch[p].find(c)==ch[p].end();p=fa[p]) ch[p][c]=np;
        if(!p) fa[np]=1;
        else
        {
            q=ch[p][c];
            if(len[q]==len[p]+1) fa[np]=q;
            else
            {
                nq=++tot;
                fa[nq]=fa[q];
                ch[nq]=ch[q];
                fa[q]=fa[np]=nq;
                len[nq]=len[p]+1;
                for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            }
        }
        last=np;
    }
         
    int main()
    {
        scanf("%s",s+1);
        int n=strlen(s+1);
        for(int i=1;i<=n;++i) 
        {
            leaf[i]=tot+1;
            extend(s[i]-'a');
        }
        for(int i=1;i<=tot;++i) v[len[i]]++;
        for(int i=1;i<=n;++i) v[i]+=v[i-1];
        for(int i=1;i<=tot;++i) sa[v[len[i]]--]=i;
        int x;
        for(int i=tot;i;--i)
        {
            x=sa[i];
            siz[fa[x]]+=siz[x];
        }
        tr1.build(1,1,n);
        tr2.build(1,1,n);
        int l,r,end;
        for(int x=2;x<=tot;++x)
        if(siz[x]==1)
        {
            l=len[fa[x]];
            r=len[x];
            end=len[x];
            tr1.change(1,1,n,end-l,end,l+1);
            tr2.change(1,1,n,end-r+1,end-l,end+1);
        }
        int a,b;
        for(int i=1;i<=n;++i)
        {
            a=tr1.query(1,1,n,i);
            b=tr2.query(1,1,n,i)-i;
            printf("%d
    ",min(a,b));
        }
        return 0;
    }
  • 相关阅读:
    SCM基础之SCM配置管理计划重要性
    SCM基础之合理设计配置库
    SCM英文术语
    中国歼20隐形战机首飞成功
    SCM基础之过程描述
    SCM基础之基线审核
    SCM基础之组织结构设计
    SCM基础之如何做到配置管理
    配置管理介绍
    软件配置管理的任务
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8986420.html
Copyright © 2011-2022 走看看