题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4787
构造两个自动机 当一个自动机大于节点上限,就将BUFF全部加入AC
有个问题就是TOP在1000的时候能AC 5000和500就会WA不是很懂为什么
代码:
#include <bits/stdc++.h>
#define sf scanf
#define pf printf
using namespace std;
const int maxn = 100000 + 10;
struct AcTrie{
int ch[maxn][2],tot,v[maxn],fail[maxn];
void Init(){
memset( ch[0] , 0 ,sizeof ch[0]);
v[0] = 0;
tot = 1;
}
int NewNode(){
memset( ch[tot] , 0, sizeof ch[0] );
v[tot] = 0;
return tot++;
}
void Insert(char * s){
int cur = 0;
while(*s){
int idx = *s - '0';
if(!ch[cur][idx]){
ch[cur][idx] = NewNode();
}
cur = ch[cur][idx];
s++;
}
v[cur] = 1;
}
void GetFail(){
queue<int> Q;Q.push(0);
fail[0] = -1;
while(!Q.empty()){
int cur = Q.front();Q.pop();
for(int idx = 0;idx < 2;++idx){
if(ch[cur][idx]){
int f = fail[cur];
while(~f && !ch[f][idx]) f = fail[f];
fail[ch[cur][idx]] = (f == -1) ? 0 : ch[f][idx];
Q.push(ch[cur][idx]);
}
}
}
}
int Search(char *s){
int cur = 0,ret = 0,f;
while(*s){
int idx = *s - '0';
if(!ch[cur][idx]){
f = fail[cur];
while(f != -1 && !ch[f][idx]) f = fail[f];
cur = (f == -1) ? 0 : ch[f][idx];
}else cur = ch[cur][idx];
f = cur;
while(f){
ret += v[f];
f = fail[f];
}
s++;
}
return ret;
}
}ac,buff;
const int maxnn = 5000000 + 50,TOP = 999;
char str[maxnn],tmp[maxnn];
void DFS(int rt1,int rt2){
ac.v[rt1] = ac.v[rt1] | buff.v[rt2];
for(int i = 0;i < 2;++i){
if(ac.ch[rt1][i] && buff.ch[rt2][i]) DFS(ac.ch[rt1][i],buff.ch[rt2][i]);
else if(!ac.ch[rt1][i] && buff.ch[rt2][i]) DFS(ac.ch[rt1][i] = ac.NewNode(),buff.ch[rt2][i]);
}
}
void getRev(int k){
int len = strlen(str + 1);
char* tmp_s = str + 1,*tmp_tmp = tmp + 1;
tmp_tmp[len] = 0;
for(int i = 0;i < len;++i) tmp_tmp[i] = tmp_s[ (i + k) % len ];
}
int main(){
int T,ca = 0;sf("%d",&T);
tmp[0] = '#';
while( T-- ){
int n,pre = 0;sf("%d",&n);
ac.Init();
buff.Init();
ac.GetFail();
buff.GetFail();
pf("Case #%d:\n",++ca);
for(int i = 0;i < n;++i){
sf("%s",str);
getRev(pre);
if(str[0] == '+') buff.Insert(tmp + 1);
else{
if(buff.tot > TOP){
DFS(0,0);
ac.GetFail();
buff.Init();
buff.GetFail();
}
else buff.GetFail();
pf("%d\n",pre = (buff.Search(tmp + 1) + ac.Search(tmp + 1)));
}
}
}
}

本文介绍了一种使用AC自动机构造双机方案解决特定编程竞赛问题的方法。该方案在节点数量达到一定上限时,将辅助自动机的所有信息合并到主自动机中,以避免超出限制。文中提供了一个完整的C++实现示例,并通过具体实例展示了如何处理字符串匹配及计数等问题。
1575

被折叠的 条评论
为什么被折叠?



