题意:
给你一串编码后的单词和一篇文章 问 编码前文章中出现了几个单词
思路:
根据题意反编码 然后AC自动机跑一下
转化字符时候注意长度 因为可能转换出‘\0‘ 所以转完后再求strlen会出错
注意 ZOJ的char默认是signed char 所以转码后要么存在unsigned char数组里 要么用int数组存 否则会错的!! 因为signed char无法表示128+的数字!!
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 51200 #define M 260 int n,m,tot,res; struct node { int next[M]; int cnt,fail,vis; void init() { memset(next,-1,sizeof(next)); fail=cnt=vis=0; } }nd[N]; int qu[N]; int head,tail; char word[N]; int code[N]; void mf() { int i,j,idx,fa; head=tail=0; for(i=0;i<M;i++) { if(nd[0].next[i]!=-1) qu[tail++]=nd[0].next[i]; } while(head<tail) { fa=qu[head++]; for(i=0;i<M;i++) { if(nd[fa].next[i]!=-1) { qu[tail++]=nd[fa].next[i]; idx=nd[fa].fail; while(idx>0&&nd[idx].next[i]==-1) idx=nd[idx].fail; if(nd[idx].next[i]!=-1) idx=nd[idx].next[i]; nd[nd[fa].next[i]].fail=idx; } } } } void fd(int len) { int i,idx,trvl; for(i=idx=0;i<len;i++) { while(idx>0&&nd[idx].next[code[i]]==-1) idx=nd[idx].fail; if(nd[idx].next[code[i]]!=-1) { trvl=idx=nd[idx].next[code[i]]; while(trvl>0&&nd[trvl].vis!=-1) { if(nd[trvl].cnt) res+=nd[trvl].cnt; nd[trvl].vis=-1; trvl=nd[trvl].fail; } } } } int bin[N*10]; int change() { int i,j,k,len,tmp; len=strlen(word); for(i=k=0;i<len;i++) { if(word[i]=='=') { k-=2; continue; } if(word[i]>='A'&&word[i]<='Z') tmp=word[i]-'A'; else if(word[i]>='a'&&word[i]<='z') tmp=word[i]-'a'+26; else if(word[i]>='0'&&word[i]<='9') tmp=word[i]-'0'+52; else if(word[i]=='+') tmp=62; else if(word[i]=='/') tmp=63; for(j=5;j>=0;j--) { if(tmp&(1<<j)) bin[k++]=1; else bin[k++]=0; } } for(i=len=0;i<k;i+=8) { for(j=i,tmp=0;j<i+8;j++) tmp=(tmp<<1)|bin[j]; code[len++]=tmp; } return len; } int main() { int i,len,j,idx; while(~scanf("%d",&n)) { tot=0; nd[0].init(); for(i=1;i<=n;i++) { scanf("%s",word); len=change(); for(j=idx=0;j<len;j++) { if(nd[idx].next[code[j]]==-1) { nd[idx].next[code[j]]=++tot; nd[tot].init(); } idx=nd[idx].next[code[j]]; } nd[idx].cnt++; } mf(); scanf("%d",&m); for(i=1;i<=m;i++) { res=0; scanf("%s",word); len=change(); fd(len); printf("%d\n",res); for(j=0;j<=tot;j++) nd[j].vis=0; } puts(""); } return 0; }
原文地址:http://blog.csdn.net/houserabbit/article/details/37937079