-
- 对病毒串建立ac自动机;
- 有一个无限长的串等价于可以一直在自动机上匹配,等价于自动机上的转移有环;
- 当然前提是去掉病毒节点的fail子树;
- 写一个dfs记录是否在栈中,来过没有找到就不必再来了再记录一个vis保证复杂度;
- 然而。。。。。。我在找环的时候呆了很久,最后写了tarjan;
- 如果你也是有些tarjan的危险想法的话注意特判转移的自环的情况;
- 对病毒串建立ac自动机;
-
bzoj2938
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=30010; 4 int n,sz,ch[N][2],fl[N],que[N],head,tail,vis[N],hd[N],o,dfn[N],idx,low[N],fg,del[N]; 5 struct Edge{int v,nt;}E[N<<1]; 6 char s[N]; 7 void adde(int u,int v){ 8 if(u==v)fg=1; 9 E[o]=(Edge){v,hd[u]};hd[u]=o++; 10 } 11 void get_fl(){ 12 for(int i=0;i<2;i++)if(ch[0][i]){ 13 que[++tail]=ch[0][i]; 14 if(!vis[ch[0][i]])adde(0,ch[0][i]); 15 }else {fg=1;return;} 16 while(head<tail){ 17 int u=que[++head]; 18 for(int i=0;i<2;i++){ 19 int&v=ch[u][i]; 20 if(!v){ 21 v=ch[fl[u]][i]; 22 if(!vis[v])adde(u,v); 23 continue; 24 } 25 fl[v]=ch[fl[u]][i]; 26 vis[v]|=vis[fl[v]]; 27 if(!vis[v])adde(u,v); 28 que[++tail]=v; 29 } 30 } 31 } 32 void tarjan(int u){ 33 if(fg)return ; 34 que[++head]=u; 35 dfn[u]=low[u]=++idx; 36 for(int i=hd[u];~i;i=E[i].nt){ 37 int v=E[i].v; 38 if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]); 39 else if(!del[v])low[u]=min(low[u],dfn[v]); 40 } 41 if(dfn[u]==low[u]){ 42 int cnt=0,v; 43 do{ 44 cnt++; 45 del[v=que[head--]]=1; 46 }while(v!=u); 47 if(cnt > 1)fg=1; 48 } 49 } 50 int main(){ 51 // freopen("bzoj2938.in","r",stdin); 52 // freopen("bzoj2938.out","w",stdout); 53 memset(hd,-1,sizeof(hd)); 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++){ 56 scanf("%s",s+1); 57 int len=strlen(s+1),u=0; 58 for(int j=1;j<=len;j++){ 59 if(!ch[u][s[j]-'0'])ch[u][s[j]-'0']=++sz; 60 u=ch[u][s[j]-'0']; 61 } 62 vis[u]=1; 63 } 64 get_fl(); 65 head=0;tarjan(0); 66 if(fg)puts("TAK");else puts("NIE"); 67 return 0; 68 }
相关文章: