zoukankan      html  css  js  c++  java
  • 【BZOJ3172】[TJOI2013]单词

    【BZOJ3172】[TJOI2013]单词

    题面

    bzoj

    luogu

    题解

    我们考虑一下$AC$自动机的匹配过程

    发现每个字符串的出现次数就是$fail$树上串最后字符节点的权值之和

    然后就比较简单了

    代码

    #include <iostream> 
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm> 
    #include <queue> 
    using namespace std; 
    const int MAX_N = 1e6 + 5;
    int c[MAX_N][26], size[MAX_N], End[MAX_N], fail[MAX_N], tot;
    int q[MAX_N], cnt; 
    void insert(char *s, int id) { 
    	int o = 0; 
    	for (int l = strlen(s), i = 0; i < l; i++) { 
    		int son = s[i] - 'a'; 
    		if (!c[o][son]) c[o][son] = ++tot; 
    		o = c[o][son]; ++size[o]; 
    	} 
    	End[id] = o; 
    } 
    void build() {
    	static queue<int> que;
    	q[++cnt] = 0; 
    	for (int i = 0; i < 26; i++) if (c[0][i]) que.push(c[0][i]), fail[c[0][i]] = 0, q[++cnt] = c[0][i]; 
    	while (!que.empty()) { 
    		int o = que.front(); que.pop(); 
    		for (int i = 0; i < 26; i++)
    			if (c[o][i]) fail[c[o][i]] = c[fail[o]][i], que.push(c[o][i]), q[++cnt] = c[o][i]; 
    			else c[o][i] = c[fail[o]][i]; 
    	} 
    } 
    int N; char s[MAX_N]; 
    int main () { 
    	scanf("%d", &N); 
    	for (int i = 1; i <= N; i++) scanf("%s", s), insert(s, i); 
    	build(); 
    	for (int i = cnt; i; i--) size[fail[q[i]]] += size[q[i]]; 
    	for (int i = 1; i <= N; i++) printf("%d
    ", size[End[i]]); 
    	return 0; 
    } 
    
  • 相关阅读:
    Annotation
    bulid tools
    Git&Version Control
    uri&url
    HTTP &RFC
    git创建新分支
    git忽略提交文件
    redis集群搭建
    java中的线程安全是什么:
    Spring事务传播机制与隔离级别
  • 原文地址:https://www.cnblogs.com/heyujun/p/10243419.html
Copyright © 2011-2022 走看看