zoukankan      html  css  js  c++  java
  • bzoj3172: [Tjoi2013]单词

    题目链接

    bzoj3172: [Tjoi2013]单词

    题解

    在插入单词时对于每个点都标记一下
    构建fail树
    因为AC自动机节点维护前缀,fail树的关系是公共后缀,那么可以发现,答案就是该单词的fail子树总价值

    代码

    #include<queue> 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    #define LL long long
    inline int read() { 
        int x = 0,f = 1;char c = getchar(); 
        while(c < '0'||c > '9')c = getchar(); 
        while(c <= '9' &&c >= '0')x = x * 10 + c - '0',c = getchar(); 
        return x * f; 
    } 
    #define LL long long 
    int n; 
    const int maxn = 1000097; 
    char a[maxn];
    int sz,ch[maxn][27];LL cnt[maxn]; 
    struct node {
        int v,next; 
    } edge[maxn << 1]; 
    int num,head[maxn],loc[maxn]; 
    inline void add_edge(int u,int v) { edge[++ num].v = v ;edge[num].next = head[u];head[u] = num; } 
    int insert(char *t) { 
        int len = strlen(t); 
        int now = 0; 
        for(int i = 0;i < len;++ i) { 
            int  s = t[i] - 'a'; 
            if(!ch[now][s]) ch[now][s] = ++ sz; 
            now = ch[now][s]; cnt[now] ++; 
        } 
        return now; 
    } 
    int fail[maxn],q[maxn]; 
    void get_fail(int l = 0,int r = 0 ) { 
        for(int i = 0;i <= 25;++ i)if(ch[0][i]) q[++ r] = ch[0][i]; 
        while(l < r) { 
            int u = q[++ l]; 
            for(int i = 0;i <= 25;++ i) { 
                int v = ch[u][i]; 
                if(v) fail[v] = ch[fail[u]][i],q[++ r] = v; 
                else ch[u][i] = ch[fail[u]][i]; 
            } 
        } 
    } 
    void dfs(int x,int fa = 0) {  
        for(int i = head[x];i;i = edge[i].next) {  
            int v = edge[i].v;  
            if(v != fa) {dfs(v,x),cnt[x] += cnt[v];}   
        }   
    }  
    int main() { 
        n = read();  
        for(int i = 1;i <= n;++ i) {  
            scanf("%s",a);  
            loc[i] = insert(a);  
        }  
        get_fail();  
        for(int i = 1;i <= sz;++ i) { 
            add_edge(fail[i],i); 
        } 
        dfs(0); 
        for(int i = 1;i <= n;++ i) { 
            printf("%d
    ",cnt[loc[i]]); 
        } 
        return 0;
    }
    
  • 相关阅读:
    转载 linux 僵尸进程,讲的很透彻
    linux 程序自动运行总结
    使用__FILE__和__LINE__定位错误
    CURL简单使用
    阿里云域名绑定IP
    使用PHPEXCEL导入数据到数据库
    关于使用ueditor时候遇到的情况
    TP5使用PHPMAILER发送邮件
    使用ajax,结合jquery,php实现图片上传预览功能
    mysql关于数据量大的时候分页分批处理
  • 原文地址:https://www.cnblogs.com/sssy/p/9270189.html
Copyright © 2011-2022 走看看