bzoj2938: [Poi2000]病毒
被Star_Feel大爷带着做题
明显大力AC机然后找环
本来我一开始想的是先去有另一个病毒为前缀的病毒,结果今天早上写的时候偷懒没写
结果跳fail的时候会跳到中间。。。无语,Star_Feel大爷叫我son或一下now和fail就过了
还有神仙是直接把fail接到儿子的更流弊了。。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct Trie { int w[2],fail; bool ed; }tr[31000];int trlen; char ss[31000]; void insert() { int now=0; int len=strlen(ss+1); for(int i=1;i<=len;i++) { int x=ss[i]-'0'; if(tr[now].w[x]==0) tr[now].w[x]=++trlen; now=tr[now].w[x]; } tr[now].ed=true; } int list[31000]; void bfs() { int head=1,tail=2;list[1]=0; while(head!=tail) { int now=list[head]; for(int x=0;x<=1;x++) { int son=tr[now].w[x]; if(son==0)continue; tr[son].ed|=tr[now].ed; if(now==0)tr[son].fail=0; else { int p=tr[now].fail; while(p!=0&&tr[p].w[x]==0)p=tr[p].fail; tr[son].fail=tr[p].w[x]; tr[son].ed|=tr[tr[son].fail].ed; } list[tail++]=son; } head++; } } //------------------------AC--------------------------------------- int v[31000]; bool dfs(int now) { if(tr[now].ed==true)return false; if(v[now]>=0)return v[now]; v[now]=1; for(int x=0;x<=1;x++) { int p=now; while(p!=0&&tr[p].w[x]==0)p=tr[p].fail; if(dfs(tr[p].w[x]))return true; } v[now]=0; return false; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",ss+1), insert(); bfs(); memset(v,-1,sizeof(v)); if(dfs(0))printf("TAK\n"); else printf("NIE\n"); return 0; }
pain and happy in the cruel world.