BZOJ3277 串
Posted Stump
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3277 串相关的知识,希望对你有一定的参考价值。
https://www.lydsy.com/JudgeOnline/problem.php?id=3277
把多个串插入广义后缀自动机中,建出parent树,在树上做set启发式合并,
记录下每一个前缀在不同串出现的次数,
再对每个串暴力匹配一遍,求出答案即可.
复杂度O(nlogn)
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<string> 6 #include<set> 7 #define rep(i,s,t) for(register int i=s;i<=t;++i) 8 #define _rep(i,s,t) for(register int i=s;i>=t;--i) 9 #define Rep(i,s,t) for(register int i=s;i<t;++i) 10 using namespace std; 11 namespace IO{ 12 #define gc getchar() 13 #define pc(x) putchar(x) 14 template<typename T>inline void read(T &x){ 15 x=0;int f=1;char ch=gc; 16 while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=gc;} 17 while(ch>=‘0‘&&ch<=‘9‘)x=(x<<3)+(x<<1)+ch-‘0‘,ch=gc; 18 x*=f;return; 19 } 20 template<typename T>inline void write(T x=0){ 21 T wr[51];wr[0]=0; 22 if(x<0)pc(‘-‘),x=-x; 23 if(!x)pc(48); 24 while(x)wr[++wr[0]]=x%10,x/=10; 25 while(wr[0])pc(48+wr[wr[0]--]); 26 return; 27 } 28 } 29 using IO::read; 30 using IO::write; 31 const int N=2e5+11; 32 typedef long long ll; 33 int n,k,len; 34 string S[N]; 35 struct SAM{ 36 int las,cnt,tot,ch[N][26],l[N], 37 fa[N],c[N],pos[N],sz[N], 38 nxt[N*6],lst[N],to[N*6]; 39 set<int>s[N]; 40 ll ans; 41 SAM(){ 42 las=cnt=1; 43 } 44 inline void add(int c,int x){ 45 int np=++cnt,p=las;las=np,l[np]=l[p]+1,s[np].insert(x); 46 for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np; 47 if(!p)fa[np]=1; 48 else{ 49 int q=ch[p][c]; 50 if(l[p]+1==l[q]) 51 fa[np]=q; 52 else{ 53 int nq=++cnt;l[nq]=l[p]+1; 54 memcpy(ch[nq],ch[q],sizeof ch[q]); 55 fa[nq]=fa[q],fa[q]=fa[np]=nq; 56 for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq; 57 } 58 } 59 } 60 inline void merge(int x,int y){ 61 if(s[x].size()>s[y].size()) 62 swap(s[x],s[y]); 63 set<int>::iterator it; 64 for(it=s[x].begin();it!=s[x].end();++it) 65 s[y].insert(*it); 66 s[x].clear(); 67 } 68 inline void adde(int x,int y){ 69 nxt[++tot]=lst[x],lst[x]=tot,to[tot]=y; 70 } 71 inline void dfs(int x){ 72 for(register int e=lst[x];e;e=nxt[e]){ 73 dfs(to[e]); 74 merge(to[e],x); 75 } 76 sz[x]=s[x].size(); 77 } 78 inline void solve(){ 79 rep(i,1,cnt) 80 if(fa[i]) 81 adde(fa[i],i); 82 dfs(1); 83 rep(i,1,n){ 84 len=S[i].length(),las=1,ans=0; 85 Rep(j,0,len){ 86 las=ch[las][S[i][j]-‘a‘]; 87 for(;sz[las]<k;las=fa[las]); 88 ans+=l[las]; 89 } 90 printf("%lld ",ans); 91 } 92 puts(""); 93 } 94 }sam; 95 int main(){ 96 scanf("%d%d",&n,&k); 97 rep(i,1,n){ 98 cin>>S[i]; 99 len=S[i].length(),sam.las=1; 100 Rep(j,0,len) 101 sam.add(S[i][j]-‘a‘,i); 102 } 103 if(k>n){ 104 rep(i,1,n) 105 printf("0 "); 106 return 0; 107 } 108 sam.solve(); 109 return 0; 110 }
以上是关于BZOJ3277 串的主要内容,如果未能解决你的问题,请参考以下文章