1. 程式人生 > >洛谷 P3804 【模板】後綴自動機

洛谷 P3804 【模板】後綴自動機

ops rst ons sss har sizeof cstring n) oop

來一份模板

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 typedef long long LL;
 7 char s[1000100];
 8 int n;
 9 LL ans;
10 namespace SAM
11 {
12     int mem,np,root;
13     int len[2000100],par[2000100];
14     int trans[2000100
][26]; 15 int in[2000100],sz[2000100]; 16 void append(int ch) 17 { 18 int p=np;np=++mem;len[np]=len[p]+1; 19 for(;p&&!trans[p][ch];p=par[p]) trans[p][ch]=np; 20 if(!p) par[np]=root; 21 else 22 { 23 int q=trans[p][ch]; 24 if
(len[q]==len[p]+1) par[np]=q; 25 else 26 { 27 int nq=++mem;par[nq]=par[q];par[q]=par[np]=nq; 28 memcpy(trans[nq],trans[q],sizeof(trans[nq]));len[nq]=len[p]+1; 29 for(;p&&trans[p][ch]==q;p=par[p]) trans[p][ch]=nq;
30 } 31 } 32 sz[np]=1; 33 } 34 void build() 35 { 36 np=root=++mem; 37 for(int i=1;i<=n;i++) append(s[i]-a); 38 } 39 queue<int> q; 40 void work() 41 { 42 int i,t; 43 for(i=1;i<=mem;i++) ++in[par[i]]; 44 for(i=1;i<=mem;i++) 45 if(!in[i]) 46 q.push(i); 47 while(!q.empty()) 48 { 49 t=q.front();q.pop(); 50 if(sz[t]>1) ans=max(ans,LL(sz[t])*len[t]); 51 if(par[t]) 52 { 53 sz[par[t]]+=sz[t]; 54 --in[par[t]]; 55 if(!in[par[t]]) q.push(par[t]); 56 } 57 } 58 } 59 } 60 61 int main() 62 { 63 scanf("%s",s+1);n=strlen(s+1); 64 SAM::build();SAM::work(); 65 printf("%lld",ans); 66 return 0; 67 }

還有後綴數組強行A此題

 1 #pragma GCC optimize("Ofast")
 2 #pragma GCC target("sse3","sse2","sse")
 3 #pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
 4 #pragma GCC target("f16c")
 5 #pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
 6 #pragma GCC diagnostic error "-fwhole-program"
 7 #pragma GCC diagnostic error "-fcse-skip-blocks"
 8 #pragma GCC diagnostic error "-funsafe-loop-optimizations"
 9 #pragma GCC diagnostic error "-std=c++14"
10 #include<cstdio>
11 #include<algorithm>
12 #include<cstring>
13 #include<map>
14 using namespace std;
15 char s[1000100];
16 int n;
17 namespace SA
18 {
19     int sa[1000100],t1[1000100],t2[1000100],m=z,cnt[1000100],p;
20     int *x=t1,*y=t2,*rk=t1,*height=t2;
21     template<typename T>
22     T get(int pos,T *a)
23     {
24         return pos<=n?a[pos]:0;
25     }
26     void build()
27     {
28         int i,k;int *it,*ed;
29         for(i=1;i<=n;++i)    ++cnt[x[i]=s[i]];
30         for(it=cnt+1,ed=cnt+m+1;it!=ed;++it)    *it+=*(it-1);
31         for(i=n;i>=1;--i)    sa[cnt[x[i]]--]=i;
32         for(k=1;k<=n;k<<=1)
33         {
34             p=0;
35             for(i=n-k+1;i<=n;++i)    y[++p]=i;
36             for(i=1;i<=n;++i)    if(sa[i]>k)  y[++p]=sa[i]-k;
37             for(it=cnt+1,ed=cnt+m+1;it!=ed;++it)    *it=0;
38             for(i=1;i<=n;++i)    cnt[x[y[i]]]++;
39             for(it=cnt+1,ed=cnt+m+1;it!=ed;++it)    *it+=*(it-1);
40             for(i=n;i>=1;--i)    sa[cnt[x[y[i]]]--]=y[i];
41             swap(x,y);p=0;
42             for(i=1;i<=n;++i)
43                 x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&get(sa[i]+k,y)==get(sa[i-1]+k,y)
44                     ?p:++p;
45             if(p>=n) break;
46             m=p;
47         }
48         for(i=1;i<=n;++i)    rk[sa[i]]=i;
49         for(i=1,k=1;i<=n;++i)
50         {
51             if(k)   k--;
52             if(rk[i])
53                 while(get(sa[rk[i]-1]+k,s)==get(i+k,s)) k++;
54             height[rk[i]]=k;
55         }
56     }
57 }
58 int sz[1000100],fa[1000100];
59 int find(int x)    {return x==fa[x]?x:fa[x]=find(fa[x]);}
60 typedef pair<int,int> P;
61 typedef long long LL;
62 P tmp[1000100];
63 LL ans;
64 bool cmp(const P& a,const P& b)
65 {
66     return a>b;
67 }
68 int main()
69 {
70     int i,d,t,fx,fy;
71     scanf("%s",s+1);n=strlen(s+1);SA::build();
72     for(i=1;i<=n;i++)    fa[i]=i,sz[i]=1;
73     for(i=2;i<=n;i++)    tmp[i]=P(SA::height[i],i);
74     sort(tmp+2,tmp+n+1,cmp);
75     for(i=2;i<=n;i++)
76     {
77         d=tmp[i].first;t=tmp[i].second;
78         fx=find(t-1);fy=find(t);
79         sz[fy]+=sz[fx];fa[fx]=fy;
80         ans=max(ans,LL(sz[fy])*d);
81     }
82     printf("%lld",ans);
83     return 0;
84 }

以下是作死用map之後T掉的程序

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<map>
 5 #include<queue>
 6 using namespace std;
 7 typedef long long LL;
 8 char s[1000100];
 9 int n;
10 LL ans;
11 namespace SAM
12 {
13     int mem,np,root;
14     int len[2000100],par[2000100];
15     map<int,int> trans[2000100];
16     int in[2000100],sz[2000100];
17     void append(int ch)
18     {
19         int p=np;np=++mem;len[np]=len[p]+1;
20         for(;p&&!trans[p].count(ch);p=par[p])    trans[p][ch]=np;
21         if(!p)    par[np]=root;
22         else
23         {
24             int q=trans[p][ch];
25             if(len[q]==len[p]+1)    par[np]=q;
26             else
27             {
28                 int nq=++mem;par[nq]=par[q];par[q]=par[np]=nq;
29                 trans[nq]=trans[q];len[nq]=len[p]+1;
30                 for(;p&&trans[p].count(ch)&&trans[p][ch]==q;p=par[p])    trans[p][ch]=nq;
31             }
32         }
33         sz[np]=1;
34     }
35     void build()
36     {
37         np=root=++mem;
38         for(int i=1;i<=n;i++)    append(s[i]-a);
39     }
40     queue<int> q;
41     void work()
42     {
43         int i,t;
44         for(i=1;i<=mem;i++)    ++in[par[i]];
45         for(i=1;i<=mem;i++)
46             if(!in[i])
47                 q.push(i);
48         while(!q.empty())
49         {
50             t=q.front();q.pop();
51             if(sz[t]>1)    ans=max(ans,LL(sz[t])*len[t]);
52             if(par[t])
53             {
54                 sz[par[t]]+=sz[t];
55                 --in[par[t]];
56                 if(!in[par[t]])    q.push(par[t]);
57             }
58         }
59     }
60 }
61 
62 int main()
63 {
64     scanf("%s",s+1);n=strlen(s+1);
65     SAM::build();SAM::work();
66     printf("%lld",ans);
67     return 0;
68 }

洛谷 P3804 【模板】後綴自動機