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

    感谢dalaoWJZ的讲解。

    我们对于每一个串a[i]相当于在他parent的right集合里找一个出现位置在id-len[x]+len[parent]到id[x]-1区间的

    用主席树判存在性即可。

    至于我问了很久这个区间为什么不能往前判,原因是你每个节点都代表唯一一个子串,所以我们定性查询就可以啦。

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=4e5+10;
     4 int rt[N],num,n;
     5 char s[N];
     6 struct tree{
     7     int l,r;
     8 }t[N*50];
     9 void change(int &x,int l,int r,int p)
    10 {
    11     if(!x)x=++num;
    12     if(l==r)return;
    13     int mid=l+r>>1;
    14     if(p>mid)change(t[x].r,mid+1,r,p);
    15     else change(t[x].l,l,mid,p);
    16 }
    17 void merge(int &x,int y)
    18 {
    19     if(!x||!y){x=x+y;return;}
    20     ++num;t[num]=t[x];x=num;
    21     merge(t[x].l,t[y].l);
    22     merge(t[x].r,t[y].r);
    23 }
    24 bool query(int x,int l,int r,int L,int R)
    25 {
    26     if(!x)return 0;
    27     if(l==L&&r==R)return 1;
    28     int mid=l+r>>1;
    29     if(mid<L)return query(t[x].r,mid+1,r,L,R);
    30     else if(mid>R)return query(t[x].l,l,mid,L,R);
    31     else return query(t[x].l,l,mid,L,mid)|query(t[x].r,mid+1,r,mid+1,R); 
    32 }
    33 struct SAM
    34 {
    35     int cnt,root,last,c[N][26],f[N],dp[N],tt[N],pos[N],r[N],id[N],l[N];
    36     SAM(){cnt=0;last=root=++cnt;}
    37     void add(int x,int dd)
    38     {
    39         int now=last,a=++cnt;last=a;id[a]=dd;
    40         l[a]=l[now]+1;
    41         for(;now&&!c[now][x];now=f[now])c[now][x]=a;
    42         if(!now)f[a]=root;
    43         else{
    44             int q=c[now][x];
    45             if(l[q]==l[now]+1)f[a]=q;
    46             else{
    47                 int b=++cnt;id[b]=dd;
    48                 l[b]=l[now]+1;
    49                 f[b]=f[q];
    50                 f[a]=f[q]=b;
    51                 memcpy(c[b],c[q],sizeof(c[q]));
    52                 for(;now&&c[now][x]==q;now=f[now])c[now][x]=b;
    53             }
    54         }
    55         return;
    56     }
    57     void sort(){
    58         for(int i=1;i<=cnt;++i)tt[l[i]]++;
    59         for(int i=1;i<=n;++i)tt[i]+=tt[i-1];
    60         for(int i=1;i<=cnt;++i)r[tt[l[i]]--]=i;
    61         return;
    62     }
    63     void work()
    64     {
    65         for(int i=cnt;i>=2;--i)
    66         {
    67             int x=r[i];
    68             change(rt[x],1,n,id[x]);
    69             merge(rt[f[x]],rt[x]);
    70         }int ans=1;
    71         for(int i=2;i<=cnt;++i)
    72         {
    73             int x=r[i];
    74             if(f[x]==1){pos[x]=x,dp[x]=1;continue;}
    75             if(query(rt[pos[f[x]]],1,n,id[x]-l[x]+l[pos[f[x]]],id[x]-1))
    76             dp[x]=dp[pos[f[x]]]+1,pos[x]=x;
    77             else dp[x]=dp[pos[f[x]]],pos[x]=pos[f[x]];
    78             ans=max(ans,dp[x]);
    79         }
    80         printf("%d
    ",ans);
    81         return;
    82     }
    83 }A;
    84 int main()
    85 {
    86     scanf("%d%s",&n,s+1);
    87     for(int i=1;i<=n;++i)A.add(s[i]-'a',i);
    88     A.sort();A.work();
    89     return 0;
    90 }
  • 相关阅读:
    25个PHP游戏编程脚本代码(转)
    [AJAXJSP]使用DWR框架验证用户名是否存在
    [AJAXJSP]验证用户名存在
    [Java基础]多线程求和小例子
    [JAVA算法]求子数组的最大和
    [JQury] slideToggle闪烁问题及解决办法
    [JAVA算法]递归求Fibbonicc序列方法
    Easy ui Datagrid(下拉、复选、只输入数字、文本) 追加、删除、更改
    Easy ui DataGrid 添加复选框 与 下拉
    Easy ui DataGrid 列文字多串行问题解决方案
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8545584.html
Copyright © 2011-2022 走看看