标签:
2 3 +01 +01 ?01001 3 +01 ?010 ?011
Case #1: 2 Case #2: 1 0
#include<stdio.h> #include<string.h> #include<stdlib.h> #pragma comment(linker, "/STACK:1024000000,1024000000") char str[5000100],s1[5000100]; int head,tail; int node_num; struct node { node *fail; node *next[2]; __int64 vis,key; node() { fail=NULL; key=vis=0; for(int i=0;i<2;i++) next[i]=NULL; } }*q[8008000]; node *root1,*root2; void insert(char *s,node *root) { int temp,len,i; node *p=root; len=strlen(s); for(i=0;i<len;i++) { temp=s[i]-'0'; if(p->next[temp]==NULL) { node_num++; p->next[temp]=new node(); } p=p->next[temp]; } p->vis=1; } void build_ac(node *root) { head=tail=0; q[tail++]=root; while(head!=tail) { node *p=q[head++]; node *temp=NULL; for(int i=0;i<2;i++) { if(p->next[i]!=NULL) { if(p==root) { p->next[i]->fail=root; p->next[i]->key=p->next[i]->vis; } else { temp=p->fail; while(temp!=NULL) { if(temp->next[i]!=NULL) { p->next[i]->fail=temp->next[i]; p->next[i]->key=temp->next[i]->key+p->next[i]->vis; break; } temp=temp->fail; } if(temp==NULL) { p->next[i]->fail=root; p->next[i]->key=p->next[i]->vis; } } q[tail++]=p->next[i]; } } } } __int64 query(char *str,node *root) { __int64 ans=0; int len=strlen(str); node *p=root,*temp; for(int i=0;i<len;i++) { int x=str[i]-'0'; while(p->next[x]==NULL&&p!=root) p=p->fail; p=p->next[x]; if(p==NULL) { p=root; } temp=p; /*while(temp!=root) { ans+=temp->vis; temp=temp->fail; } */ ans+=temp->key; } return ans; } int seach(char *s,node *root) { int len=strlen(s),i,j,now; node *cur=root; for(i=0;i<len;i++) { now=s[i]-'0'; if(cur->next[now]!=NULL) { cur=cur->next[now]; } else return 0; } if(cur->vis) return 1; return 0; } void del(node *root) { if(root==NULL) return; int i; for(i=0;i<2;i++) { if(root->next[i]!=NULL) del(root->next[i]); } free(root); } void Union(node *root1,node *root2)//把ac自动机2合并到1上 { head=tail=0; q[tail++]=root1; q[tail++]=root2; int i,j; while(head!=tail) { node *r1=q[head++]; node *r2=q[head++]; for(i=0;i<2;i++) { if(r2->next[i]!=NULL) { if(r1->next[i]==NULL) { r1->next[i]=new node(); } r1->next[i]->vis|=r2->next[i]->vis; q[tail++]=r1->next[i]; q[tail++]=r2->next[i]; } } } } void shilf(char *str,__int64 num)//字符串左移num { int len=strlen(str); num%=len; num=len-num; if(!num) return; int i=0; for(i=0;i<num;i++) { s1[i]=str[len-num+i]; } for(i=num;i<len;i++) { s1[i]=str[i-num]; } for(i=0;i<len;i++) { str[i]=s1[i]; } str[len]=0; } int main() { int t,c=0; scanf("%d",&t); while(t--) { int n; root1=new node(); root2=new node(); scanf("%d",&n); printf("Case #%d:\n",++c); int i; __int64 num=0; node_num=0; build_ac(root1); for(i=0;i<n;i++) { scanf("%s",str); if(str[0]=='+') { shilf(str+1,num); if(seach(str+1,root1)||seach(str+1,root2)) continue; insert(str+1,root2); build_ac(root2); if(node_num>2500) { Union(root1,root2); del(root2); root2=new node(); build_ac(root1); build_ac(root2); node_num=0; } } else { shilf(str+1,num); // printf("%s\n",str+1); __int64 ans=query(str+1,root1)+query(str+1,root2); num=ans; printf("%I64d\n",ans); } } del(root1); del(root2); } }ac代码(离线ac自动机就)
#include<stdio.h> #include<string.h> char str[5000010],s1[5000010]; int head,tail; struct node { node *fail; node *next[2]; __int64 cnt; node() { fail=NULL; cnt=0; for(int i=0;i<2;i++) next[i]=NULL; } }*q[8000800]; node *root; void insert(char *s) { int temp,len,i; node *p=root; len=strlen(s); for(i=0;i<len;i++) { temp=s[i]-'0'; if(p->next[temp]==NULL) p->next[temp]=new node(); p=p->next[temp]; } p->cnt++; } void build_ac() { head=tail=0; q[tail++]=root; while(head!=tail) { node *p=q[head++]; node *temp=NULL; for(int i=0;i<2;i++) { if(p->next[i]!=NULL) { if(p==root) p->next[i]->fail=root; else { temp=p->fail; while(temp!=NULL) { if(temp->next[i]!=NULL) { p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(temp==NULL) { p->next[i]->fail=root; } } q[tail++]=p->next[i]; } } } } __int64 query(char *str) { __int64 ans=0; int len=strlen(str); node *p=root,*temp; for(int i=0;i<len;i++) { int x=str[i]-'0'; while(p->next[x]==NULL&&p!=root) p=p->fail; p=p->next[x]; if(p==NULL) { p=root; } temp=p; while(temp!=root)//没有&&temp->cnt { ans+=temp->cnt; //temp->cnt=-1; // temp->cnt=0; temp=temp->fail; } } return ans; } void shift(char *str,__int64 num) { int len=strlen(str); num%=len; num=len-num; if(!num) return; int i=0; for(i=0;i<num;i++) { s1[i]=str[len-num+i]; } for(i=num;i<len;i++) { s1[i]=str[i-num]; } for(i=0;i<len;i++) { str[i]=s1[i]; } } int seach(char *s) { int len=strlen(s),i,j,now; node *cur=root; for(i=0;i<len;i++) { now=s[i]-'0'; if(cur->next[now]!=NULL) { cur=cur->next[now]; } else return 0; } if(cur->cnt) return 1; return 0; } int main() { int t,c=0; scanf("%d",&t); while(t--) { int n; root=new node(); scanf("%d",&n); printf("Case #%d:\n",++c); int i; __int64 num=0; for(i=0;i<n;i++) { scanf("%s",str); if(str[0]=='+') { shift(str+1,num); if(seach(str+1)) continue; insert(str+1); } else { shift(str+1,num); build_ac(); __int64 ans=query(str+1); num=ans; printf("%I64d\n",ans); } } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDOJ 题目4787 GRE Words Revenge(在线ac自动机,离线也可做)
标签:
原文地址:http://blog.csdn.net/yu_ch_sh/article/details/47420697