BZOJ 3172: [Tjoi2013]单词 (AC自动机)

跟这道题一模一样,而且不强制在线,所以先打标记然后上传就行了.

CODE

#include<bits/stdc++.h>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
	char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
	for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 1000205;
const int C = 27;
int n, m, node[MAXN];
struct Aho_Corasick {
	int ch[MAXN][C], fail[MAXN], tot, q[MAXN];
	inline int insert(char *s) {
		int r = 0, indx;
		while(*s) {
			if(!ch[r][indx=(*s++)-'a'])
				ch[r][indx] = ++tot;
			r = ch[r][indx];
		}
		return r;
	}
	inline void build() {
		int r = 0, head = 0, tail = 0;
		fail[q[tail++]=r] = -1;
		while(head < tail) {
			r = q[head++];
			for(int v, indx = 0; indx < C; ++indx)
				if((v=ch[r][indx])) {
					q[tail++] = v;
					fail[v] = (r == 0 ? 0 : ch[fail[r]][indx]);
				}
				else ch[r][indx] = (r == 0 ? 0 : ch[fail[r]][indx]);
		}
	}
	int ans[MAXN];
	void modify(char *s) {
		int r = 0, indx;
		while(*s)
			++ans[r = ch[r][indx=(*s++)-'a']];
        //直接用上面的队列
        for(int i = tot; i; --i)
            ans[fail[q[i]]] += ans[q[i]];
	}
}trie;
char s[MAXN], S[MAXN];
int main() {
	read(n); int now = 0;
	for(int i = 1; i <= n; ++i) {
		scanf("%s", s), node[i] = trie.insert(s);
		for(int j = 0; s[j]; ++j)
            S[now++] = s[j];
        S[now++] = 'z'+1; //插一个特殊符号
	}
	trie.build();
	trie.modify(S);
	for(int i = 1; i <= n; ++i) printf("%d\n", trie.ans[node[i]]);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值