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\n",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 }

 

posted @ 2018-03-11 20:16  大奕哥&VANE  阅读(351)  评论(0编辑  收藏  举报