zoukankan      html  css  js  c++  java
  • POJ1743 Musical Theme [后缀自动机]

    题意:不重叠最长重复子串


    后缀数组做法:http://www.cnblogs.com/candy99/p/6227659.html

    后缀自动机的话,首先|Right|>=2 然后min(t[u].val,最右r-最左r-1)>=4就可以了

    注意判断条件不能写错哦 并且需要两者取min

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=4e4+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    int n,m,k;
    int c[N],a[N],d[N],l[N],r[N];
    int s[N];
    struct State{
        int ch[180],par,val;
    }t[N];
    int sz,root,last;
    inline int nw(int _){t[++sz].val=_;return sz;}
    inline void iniSAM(){sz=0;root=last=nw(0);}
    void extend(int c,int i){
        int p=last,np=nw(t[p].val+1); d[np]=1;l[np]=r[np]=i;
        for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
        if(!p) t[np].par=root;
        else{
            int q=t[p].ch[c];
            if(t[q].val==t[p].val+1) t[np].par=q;
            else{
                int nq=nw(t[p].val+1);
                memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
                t[nq].par=t[q].par;
                t[q].par=t[np].par=nq;
                for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
            }
        }
        last=np;
    }
    void RadixSort(){
        for(int i=0;i<=n;i++) c[i]=0; 
        for(int i=1;i<=sz;i++) c[t[i].val]++;
        for(int i=1;i<=n;i++) c[i]+=c[i-1];
        for(int i=sz;i>=1;i--) a[c[t[i].val]--]=i; 
    }
    void solve(){
        RadixSort();
        int ans=0;
        for(int i=sz;i>=1;i--){
            int u=a[i],par=t[u].par;
            d[par]+=d[u];
            l[par]=min(l[par],l[u]);
            r[par]=max(r[par],r[u]);
            if(d[u]>=2&&min(t[u].val,r[u]-l[u]-1)>=4) ans=max(ans,min(t[u].val,r[u]-l[u]-1));
            if(t[u].val<4) break;
        }
        if(ans<4) puts("0");
        else printf("%d
    ",ans+1);
    }
    int main(){
        freopen("in","r",stdin);
        while((n=read())){
            n--;
            memset(t,0,sizeof(t));
            memset(d,0,sizeof(d));memset(r,0,sizeof(r));memset(l,127,sizeof(l));
            iniSAM();
            int last=read(),x;
            for(int i=1;i<=n;i++){
                x=read();
                s[i]=x-last+88;
                last=x;
                extend(s[i],i);
            }
            solve();
        }
    }
  • 相关阅读:
    产品微谈
    SVN回滚机制
    super究竟是个啥?
    PM12条
    CocoaPods初体验
    UIView局部点击
    Memory cycles about Block
    About "self"
    openfire学习(一)
    WPF菜单和布局(2)
  • 原文地址:https://www.cnblogs.com/candy99/p/6379485.html
Copyright © 2011-2022 走看看