• cf 700e(sam好题,线段树维护right)


    代码参考:http://blog.csdn.net/qq_33229466/article/details/79140428

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=400005;
    int n,mx[maxn],ch[maxn][26],fa[maxn],last=1,id[maxn],tot=1;
    int dp[maxn],pos[maxn],cnt,b[maxn],c[maxn],root[maxn],ans;
    char s[maxn];
    struct node{
        int l,r;
    }tr[maxn*50];
    void add(int i,int x){
        int p,q,np,nq;
        p=last;last=np=++tot;mx[np]=mx[p]+1;id[np]=i;
        for(;!ch[p][x]&&p;p=fa[p])ch[p][x]=np;
        if(!p)fa[np]=1;
        else{
            q=ch[p][x];
            if(mx[q]==mx[p]+1)fa[np]=q;
            else{
                nq=++tot;mx[nq]=mx[p]+1;id[nq]=i;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];
                fa[q]=fa[np]=nq;
                for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
            }
        }    
    }
    void ins(int &d,int l,int r,int x){
        if(!d)d=++cnt;
        if(l==r)return;
        int mid=l+r>>1;
        if(x<=mid)ins(tr[d].l,l,mid,x);
        else ins(tr[d].r,mid+1,r,x);
    }
    int merge(int x,int y){
        if(!x||!y)return x+y;
        int d=++cnt;
        tr[d].l=merge(tr[x].l,tr[y].l);
        tr[d].r=merge(tr[x].r,tr[y].r);
        return d;
    }
    bool query(int d,int l,int r,int x,int y){
        if(!d)return 0;
        if(l==x&&r==y)return 1;
        int mid=l+r>>1;
        if(x<=mid&&query(tr[d].l,l,mid,x,min(y,mid)))return 1;
        if(y>mid&&query(tr[d].r,mid+1,r,max(x,mid+1),y))return 1;
        return 0;
    }
    void build(){
        for(int i=1;i<=tot;++i)b[mx[i]]++;
        for(int i=1;i<=tot;++i)b[i]+=b[i-1];
        for(int i=tot;i>=1;--i)c[b[mx[i]]--]=i;
        for(int i=tot;i>=2;--i){
            ins(root[c[i]],1,n,id[c[i]]);
            root[fa[c[i]]]=merge(root[fa[c[i]]],root[c[i]]);
        }
    }
    int main(){
        cin>>n;
        scanf("%s",s+1);
        for(int i=1;i<=n;++i)add(i,s[i]-'a');
        build();
        ans=1;
        for(int i=2;i<=tot;++i){
            int x=c[i];
            if(fa[x]==1)dp[x]=1,pos[x]=x;
            else if(query(root[pos[fa[x]]],1,n,id[x]-mx[x]+mx[pos[fa[x]]],id[x]-1)){dp[x]=dp[fa[x]]+1;pos[x]=x;}
            else {dp[x]=dp[fa[x]];pos[x]=pos[fa[x]];}
            ans=max(ans,dp[x]);
        }
        cout<<ans;
        return 0;
    } 
  • 相关阅读:
    学习Spring.Net:1.简单的应用之控制台
    学习Memcached:2基本应用之控制台使用
    学习Memcached:1基本配置与安装
    C#IAsyncResult异步回调函数的解释
    C# JSON格式数据高级用法
    C#CRC16 Modbus 效验算法
    第一篇编程笔记
    SqlParameter 操作 image 字段
    C# 对象复制
    利用触发器实现数据同步
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8541997.html
Copyright © 2020-2023  润新知