BZOJ3473 字串 廣義字尾自動機

2021-08-15 11:35:26 字數 1148 閱讀 6766

今天主攻了下sam 好多東西以前都沒理解到

對於這道題 我們建乙個自動機存所有串 每個穿last從1開始

對於自動機上每個點額外記乙個cnt 表示能匹配到這個點的不同串個數

建完對每個串在自動機上匹配 把到的每個點x和par[x],par[par[x]]…的cnt++

然後就從父親往兒子傳遞一下 這樣每個點i就存了所有

≤ ≤

len[i]的數量 這裡我用的拓撲序轉移

最後再對每個串在自動機上跑一遍 統計答案就好啦~

#include

#define bug(x) cout<<(#x)<<" "<<(x)<#define ll long long

/*char *tt,*mo,but[(1<<15)+2];

#define getchar() ((tt==mo&&(mo=(tt=but)+fread(but,1,1<<15,stdin),tt==mo))?-1:*tt++)//*/

using

namespace

std;

const

int n=2e5+5;

inline

int read()

while(ch>='0'&&ch<='9')

return x*f;

}ll ans[n];

int n,k,amaz,tot,rt,last,cnt[n],ch[n][27],len[n],par[n],l[n],tmp[n],sum[n],dig[n],vis[n];

string a[n];

void extend(int x)

}}void top()

}for(int i=amaz;i;i--) sum[tmp[i]]+=sum[par[tmp[i]]];

}int main()

for(int j=1;j<=n;j++)}}

for(int i=1;i<=tot;i++) dig[par[i]]++,sum[i]=(cnt[i]>=k)?(len[i]-len[par[i]]):0;

top();

for(int j=1;j<=n;j++)

printf("%lld ",ans[j]);

}return

0;}

BZOJ 3473 字串 廣義字尾自動機

time limit 20 sec memory limit 256 mb submit 354 solved 160 submit status discuss 給定n個字串,詢問每個字串有多少子串 不包括空串 是所有n個字串中至少k個字串的子串?第一行兩個整數n,k。接下來n行每行乙個字串。一行...

KMP 字串 BZOJ4974字串大師

在kmp演算法中,fai lfail fail 指標有乙個特殊的性質,i f aili i fail i i fail i 是前i個字元的最小迴圈節大小。所以這題相當於就是說,給了你每個點的fail指標,求乙個滿足的字串。那麼按照建fail指標的方式倒過來做就好了 include include i...

BZOJ4974 字串大師

不難發現結論pe ri i nex ti,nex t 就是kmp裡的失配陣列。考慮構造乙個字串 s 滿足上述ne xt陣列,定義 i 的失配集為 n exti 1 1 的失配集。若ne xti 0 則si sne xti 若ne xti 0 則 i 必須和其失配集中的字元互不相同,因為字典序要最小,...