生活随笔
收集整理的這篇文章主要介紹了
[BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
差分之后就是求多串LCS。
對其中一個串建SAM,然后把其它串放在上面跑。
對SAM上的每個狀態都用f[x]記錄這個狀態與當前串的最長匹配長度,res[x]是對每次的f[x]取最小值。答案就是res[]的最大值。
考慮f[x]的求法,把s[]放在SAM上跑時,若下一個能正常匹配(即son[x][c]!=0)則直接len++,否則用經典的跳父親,找到第一個son[k][c]!=0的點k,len=mx[k]+1,x=son[k][c]。
每次更新最終匹配到的狀態的f[]。同時注意到出現次數可以向父親傳遞,于是Radixsort之后經典DP轉移最長長度即可。
1 #include<map>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
6 typedef
long long ll;
7 using namespace std;
8
9 const int N=
500010;
10 int n,m,x,len,fir,lst=
1,cnt=
1,ans,res[N],s[N],f[N],mx[N],fa[N],c[N],q[N];
11 map<
int,
int>
son[N];
12
13 void ext(
int c){
14 int p=lst,np=lst=++cnt; mx[np]=mx[p]+
1;
15 while (p && !son[p][c]) son[p][c]=np,p=
fa[p];
16 if (!p) fa[np]=
1;
17 else{
18 int q=
son[p][c];
19 if (mx[q]==mx[p]+
1) fa[np]=
q;
20 else{
21 int nq=++cnt; mx[nq]=mx[p]+
1; son[nq]=
son[q];
22 while (p && son[p][c]==q) son[p][c]=nq,p=
fa[p];
23 fa[nq]=fa[q]; fa[q]=fa[np]=
nq;
24 }
25 }
26 }
27
28 void Radix(){
29 rep(i,
1,cnt) c[mx[i]]++
;
30 rep(i,
1,cnt) c[i]+=c[i-
1];
31 for (
int i=cnt; i; i--) q[c[mx[i]]--]=
i;
32 rep(i,
1,cnt) res[i]=
mx[i];
33 }
34
35 void Go(
int s[],
int n){
36 int x=
1,len=
0;
37 rep(i,
1,n){
38 int c=
s[i];
39 if (son[x][c]) x=son[x][c],f[x]=max(f[x],++
len);
40 else{
41 while (x && !son[x][c]) x=
fa[x];
42 if (!x) x=
1,len=
0;
else len=mx[x]+
1,x=son[x][c],f[x]=
max(f[x],len);
43 }
44 }
45 for (
int i=cnt; i; i--
){
46 int x=q[i]; res[x]=
min(res[x],f[x]);
47 if (f[x] && fa[x]) f[fa[x]]=
mx[fa[x]];
48 f[x]=
0;
49 }
50 }
51
52 int main(){
53 scanf(
"%d%d%d",&n,&len,&
fir);
54 rep(i,
1,len-
1) scanf(
"%d",&x),s[i]=x-fir,fir=
x;
55 len--; rep(i,
1,len) ext(s[i]);
56 Radix();
57 rep(i,
2,n){
58 scanf(
"%d%d",&len,&
fir);
59 rep(i,
1,len-
1) scanf(
"%d",&x),s[i]=x-fir,fir=
x;
60 len--
; Go(s,len);
61 }
62 rep(i,
2,cnt) ans=
max(ans,res[i]);
63 printf(
"%d\n",ans+
1);
64 return 0;
65 }
?
?
轉載于:https://www.cnblogs.com/HocRiser/p/9441117.html
總結
以上是生活随笔為你收集整理的[BZOJ4698][SDOI2008]Sandy的卡片(后缀自动机)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。