这个题解码部分比较繁琐,剩下就是裸AC自动机了。 代码能力不强竟然调试了一天。。。。 #includecstdio#includecstring#includequeue#includecstdlibconst int kind=256;using namespace std;char b[3000]; //a模式串
这个题解码部分比较繁琐,剩下就是裸AC自动机了。
代码能力不强竟然调试了一天。。。。
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
const int kind=256;
using namespace std;
char b[3000]; //a模式串,b为匹配串
bool vis[550];
int bb[3000];
int mp[200];
int length;
struct trie{
struct trie * fail,*next[kind];
int count;
int id;
trie(){
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
};
struct trie * root;
void insert(int* str,int len,int id){
int i,tem;
struct trie *p,*q;
p=root;
for(i=0;i<len;i++){
tem=str[i];
if(p->next[tem]==NULL){
q=(struct trie*)calloc(1,sizeof(struct trie));
q->count=0;
q->fail=NULL;
memset(q->next,NULL,sizeof(q->next));
p->next[tem]=q;
}
p=p->next[tem];
}
p->count+=1;
p->id=id;
}
void buildac(){
int i;
struct trie *p,*tem;
queue<struct trie *>q;
root->fail=NULL;
q.push(root);
while(!q.empty()){
tem=q.front();
q.pop();
for(i=0;i<kind;i++){
if(tem->next[i]!=NULL){
if(tem==root)
tem->next[i]->fail=root;
else{
p=tem->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
tem->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
tem->next[i]->fail=root;
}
q.push(tem->next[i]);
}
}
}
}
int query(int *str,int len){
int i,tem,result=0;
struct trie* tmp=root,*p;
for(i=0;i<len;i++){
tem=str[i];
while(tmp->next[tem]==NULL && tmp!=root)
tmp=tmp->fail;
tmp=tmp->next[tem];
if(tmp==NULL)
tmp=root;
p=tmp;
while(p!=root && vis[p->id]==0){ //每到一个位置就加上p->count,以及以他的后缀为前缀的单词
if(p->id!=0)
vis[p->id]=1; //这里我WA了一天
result+=p->count;
p=p->fail;
}
}
return result;
}
void decode(){
int i,j,len;
len=strlen(b);
if(b[len-1]=='=' && b[len-2]=='=')
length=((len-2)*6-4)/8;
else if(b[len-1]=='=' && b[len-2]!='=')
length=((len-1)*6-2)/8;
else if(b[len-1]!='=' && b[len-2]!='=')
length=len*6/8;
for(i=0,j=0;j<len-4;i+=3,j+=4){
bb[i]=(mp[b[j]]<<2)+(mp[b[j+1]]>>4);
bb[i+1]=((mp[b[j+1]]&15)<<4)+(mp[b[j+2]]>>2);
bb[i+2]=((mp[b[j+2]]&3)<<6)+(mp[b[j+3]]);
}
bb[i]=(mp[b[j]]<<2)+(mp[b[j+1]]>>4);
if(b[len-2]!='=')
bb[i+1]=((mp[b[j+1]]&15)<<4)+(mp[b[j+2]]>>2);
if(b[len-1]!='=')
bb[i+2]=((mp[b[j+2]]&3)<<6)+(mp[b[j+3]]);
}
void init(){
int i;
for(i='A';i<='Z';i++)
mp[i]=i-'A';
for(i='a';i<='z';i++)
mp[i]=i-'a'+26;
for(i='0';i<='9';i++)
mp[i]=i-'0'+52;
mp['+']=62;
mp['/']=63;
}
void destroy(struct trie * r){
for(int i=0;i<kind;i++)
if(r->next[i]!=NULL)
destroy(r->next[i]);
delete(r);
}
int main(){
//freopen("a.txt","r",stdin);
//freopen("c.txt","w",stdout);
int t,T,n,m,i,j,sum;
init();
while(scanf("%d",&n)!=EOF){
root=(struct trie*)calloc(1,sizeof(struct trie));
root->fail=NULL;
root->count=0;
memset(root->next,NULL,sizeof(root->next));
for(i=1;i<=n;i++){
scanf("%s",b);
memset(bb,0,sizeof(bb));
decode();
//printf("*****");
//for(int k=0;k<length;k++)
// printf("%d ",bb[k]);
//printf("\n");
insert(bb,length,i);
}
buildac();
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%s",b);
memset(bb,0,sizeof(bb));
decode();
//printf("*****");
//for(int k=0;k<length;k++)
// printf("%d ",bb[k]);
//printf("\n");
memset(vis,0,sizeof(vis));
printf("%d\n",query(bb,length));
}
printf("\n");
destroy(root); //这里释放内存空间降低内存使用
}
return 0;
}
写了个暴跑程序对拍才看出哪错了。。。