省队集训day6 B

一道AC自动机题····

一定要把一个节点没有的儿子接到它fai的儿子,否则会卡到n^2的·······

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<ctime>
 6 #define maxn 1048580
 7 #define maxl 10005
 8 using namespace std;
 9 typedef long long int64;
10 char ch,s[maxl];
11 int fuckwmj=0;
12 int n,l,head,tail,list[maxn];
13 int64 len;
14 struct Map{
15     int n,ans,ind[maxn],tot,now[maxn],son[maxn<<1],pre[maxn<<1],dep[maxn];
16     void init(int idx){
17         n=idx,ans=tot=0;
18         memset(ind,0,sizeof(ind));
19         memset(now,0,sizeof(now));
20         memset(dep,0,sizeof(dep));
21     }
22     void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b,ind[b]++;}
23     void solve(){
24         head=0,tail=0;
25         for (int i=0;i<=n;i++) if (!ind[i]) list[++tail]=i,dep[i]=0;
26         while (head<tail){
27             int u=list[++head];
28             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]){
29                 ind[v]--,dep[v]=max(dep[v],dep[u]+1);
30                 if (!ind[v]) list[++tail]=v;
31             }
32         }
33         for (int i=0;i<=n;i++) if (ind[i]){puts("Yes");return;}
34         for (int i=0;i<=n;i++) ans=max(ans,dep[i]);
35         if (ans>=len) puts("Yes");
36         else puts("No");
37     }
38 }dag;
39 struct trie{
40     int idx,son[maxn][2],fai[maxn];
41     bool ok[maxn],bo[maxn];
42     void clear(){
43         idx=0;
44         memset(son,0,sizeof(son));
45         memset(fai,0,sizeof(fai));
46         memset(ok,0,sizeof(ok));    
47         memset(bo,0,sizeof(bo));
48     }
49     void insert(){
50         int p=0;
51         for (int i=1,op=(s[i]=='T');i<=l;p=son[p][op],i++,op=(s[i]=='T'))
52             if (!son[p][op]) son[p][op]=++idx;
53         ok[p]=1;
54     }
55     void get_fai(){
56         head=0,tail=1,list[1]=0,fai[0]=-1,bo[0]=1;
57         while (head<tail){
58             int u=list[++head];
59             for (int ch=0,v=son[u][ch],t;ch<=1;v=son[u][++ch]) 
60                 if (v&&!bo[v]){
61                     bo[v]=1,list[++tail]=v;
62                     for (t=fai[u];t>=0&&!son[t][ch];t=fai[t]);
63                     if (t>=0) fai[v]=son[t][ch]; else fai[v]=0;
64                     if (!son[v][0]) son[v][0]=son[fai[v]][0];
65                     if (!son[v][1]) son[v][1]=son[fai[v]][1];
66                     ok[v]=ok[v]|ok[u]|ok[fai[v]];
67                 }
68         }
69         dag.init(idx);
70         head=0,tail=1,list[1]=0,bo[0]=1;
71         memset(bo,0,sizeof(bo));
72         while (head<tail){
73             int u=list[++head];
74             for (int ch=0,v=son[u][ch];ch<=1;v=son[u][++ch])
75                 if (v&&!ok[v]){
76                     dag.put(u,v);
77                     if (!bo[v]) bo[v]=1,list[++tail]=v;                
78                 }
79         }
80     }
81 }T;
82 void get(){
83     for (ch=getchar();ch!='A'&&ch!='T';ch=getchar());
84     for (l=0;ch=='A'||ch=='T';s[++l]=ch,ch=getchar());
85 }
86 int main(){
87     while (cin>>n>>len){
88         T.clear();
89         for (int i=1;i<=n;i++) get(),T.insert();
90         T.get_fai(),dag.solve();
91     }
92     return 0;
93 }
原文地址:https://www.cnblogs.com/chenyushuo/p/4630386.html