[AC自动机]HDOJ3695 Computer Virus on Planet Pandora
题意:给t、n,t个案例,n个字符串
下面给n+1个字符串,n个互不相同的小串,最后一个是模式串
模式串会出现[qx]的形式,q为数字,x为一个字母
问n个小串在模式串中出现的个数,正着出现、反着出现都算。
蛮裸的ac自动机,本来想着在query里面把找到过的end清零,把模式串展开正着反着找两遍,那即使再找到加零也不影响。但是超时了。。。
于是把找到过的end标为-1,-1了就不再找下去,就可以了~上代码
#include <cstdio> #include <cstdlib> #include <cstring> #include <climits> #include <cctype> #include <cmath> #include <string> #include <sstream> #include <iostream> #include <algorithm> #include <iomanip> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> typedef long long LL; typedef long double LD; const double eps=1e-8; #define pi acos(-1.0) #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 typedef pair<int, int> PI; typedef pair<int, PI> PP; #ifdef _WIN32 #define LLD "%I64d" #else #define LLD "%lld" #endif //#pragma comment(linker, "/STACK:1024000000,1024000000") //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;} //inline int read(){char ch=‘ ‘;int ans=0;while(ch<‘0‘ || ch>‘9‘)ch=getchar();while(ch<=‘9‘ && ch>=‘0‘){ans=ans*10+ch-‘0‘;ch=getchar();}return ans;} //inline void print(LL x){printf(LLD, x);puts("");} //inline void read(double &x){char c = getchar();while(c < ‘0‘) c = getchar();x = c - ‘0‘; c = getchar();while(c >= ‘0‘){x = x * 10 + (c - ‘0‘); c = getchar();}} //inline void sc(LL &x){scanf(LLD, &x);} struct Trie { int next[5000100][26], fail[5000100], end[5000100]; int root, L; int newnode() { for(int i=0;i<26;i++) next[L][i]=-1; end[L++]=0; return L-1; } void init() { L=0; root=newnode(); } void insert(char buf[]) { int len=strlen(buf); int now=root; for(int i=0;i<len;i++) { if(next[now][buf[i]-‘A‘]==-1) next[now][buf[i]-‘A‘]=newnode(); now=next[now][buf[i]-‘A‘]; } end[now]++; } void build() { queue<int> Q; fail[root]=root; for(int i=0;i<26;i++) if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; Q.push(next[root][i]); } while(!Q.empty()) { int now=Q.front(); Q.pop(); for(int i=0;i<26;i++) if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } int query(char buf[]) { int len=strlen(buf); int now=root; int res=0; for(int i=0;i<len;i++) { now=next[now][buf[i]-‘A‘]; int tmp=now; while(tmp!=root && end[tmp]!=-1) { res+=end[tmp]; //printf("%d %d\n", tmp, end[tmp]); end[tmp]=-1; tmp=fail[tmp]; } } return res; } }ac; char buf[5200010], tmp[5200010]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); ac.init(); for(int i=0;i<n;i++) { scanf("%s", buf); ac.insert(buf); // int LEN=strlen(buf); // reverse(buf, buf+LEN); // ac.insert(buf); } ac.build(); scanf("%s", tmp); int LEN=strlen(tmp), d=0; for(int i=0;i<LEN;i++) if(tmp[i]==‘[‘) { int cur=i+1, num=0; while(isdigit(tmp[cur])) num=num*10+tmp[cur++]-‘0‘; fill(buf+d, buf+d+num, tmp[cur]); i=cur+1, d+=num; } else buf[d++]=tmp[i]; buf[d]=‘\0‘; // puts(buf); // for(int i=0;i<ac.L;i++) // printf("%d %d\n", i, ac.end[i]); int ans=ac.query(buf); reverse(buf, buf+d); printf("%d\n", ans+ac.query(buf)); } return 0; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。