zoukankan      html  css  js  c++  java
  • [BZOJ2938][Poi2000]病毒

    题目描述:https://www.lydsy.com/JudgeOnline/problem.php?id=2938

    解析:做了这个题对AC自动机有了更深的理解。先建立补全的AC自动机,发现如果有无限长的串使得任意一个原串都不在这个串中,一定满足这个补全的AC自动机在不经过叶子结点的情况下有环。简略证明一下:发现一个点跳fail的过程的实质即为在一个字符串后面增加一个字符,如果在不经过叶子结点的情况下有环,说明这个串可以无限延伸。怎么在图中判环呢?可以从原点开始dfs,建立两个标记数组,一个用来标记走没走过,走过的点不能再次走,否则会出现死循环。一个用来标记是否在栈中,如果重复出现在栈中则说明有换,回溯的时候记得要把标记清空。

    细节:1.这个补全的图中可以有自环,循环节为0或1。2.叶子结点的标记要下传。3.不要在某谷交,数据很水。

    附上代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int MAXL=30005,MAXN=2005;
    char s[MAXL];
    int n;
    int go[MAXN*10][2];
    int ndnum=0;
    int fail[MAXN*20];
    bool is_end[MAXN*20];
    queue<int> q;
    int v[MAXN*20],used[20*MAXN];
    
    void insert(){
        int len=strlen(s+1);
        int now=0;
        for(int i=1;i<=len;i++){
            int c=s[i]-'0';
            if(!go[now][c]) go[now][c]=++ndnum;
            now=go[now][c];
        }
        is_end[now]=1;
    }
    
    void get_fail(){
        for(int i=0;i<=1;i++) 
            if(go[0][i]) q.push(go[0][i]);
        while(q.size()){
            int x=q.front();q.pop();
            for(int i=0;i<=1;i++){
                if(go[x][i]){
                    int t=fail[x];
                    fail[go[x][i]]=go[t][i];
                    q.push(go[x][i]);
                    is_end[go[x][i]]|=is_end[go[t][i]];
                }
                else 
                    go[x][i]=go[fail[x]][i];
            }
        }
    }
    
    void dfs(int x){
        v[x]=1;used[x]=1;
        for(int i=0;i<=1;i++){
            if(!is_end[go[x][i]]){
                if(v[go[x][i]]){
                    printf("TAK");
                    exit(0);
                }
                else if(!used[go[x][i]]) dfs(go[x][i]);
            }
        }
        v[x]=0;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            insert();
        }
        get_fail();
        dfs(0);
        printf("NIE");
        return 0;
    }
    View Code
  • 相关阅读:
    webpack查缺补漏
    使用express、react、webpack打包、socket.io、mongodb、ant.design、less、es6实现聊天室
    理解restful 架构 && RESTful API设计指南
    socket.io
    数学图形(1.7)圆内旋轮线
    数学图形(1.6)抛物线
    数学图形(1.5)克莱线
    数学图形(1.4)心形线
    数学图形(1.3)旋轮线
    数学图形(1.2)Sin曲线
  • 原文地址:https://www.cnblogs.com/JoshDun/p/11210269.html
Copyright © 2011-2022 走看看