HDU 3695 Computer Virus on Planet Pandora(オートマチック)
2868 ワード
タイトルリンク:http://acm.hdu.edu.cn/showproblem.php?pid=3695
題意:いくつかのウイルス列と大きな列sを与え、sがウイルス列またはその逆列を含む場合、私たちはそのウイルス列を含むと言った.問sにはどのくらいのウイルス列が含まれていますか?
标题:ウイルス列をオートマトンに挿入する.sとその逆串で走ります.
題意:いくつかのウイルス列と大きな列sを与え、sがウイルス列またはその逆列を含む場合、私たちはそのウイルス列を含むと言った.問sにはどのくらいのウイルス列が含まれていますか?
标题:ウイルス列をオートマトンに挿入する.sとその逆串で走ります.
const int N=6000005;
struct node
{
int next[26],fail,flag,t;
void init()
{
clr(next,-1);
fail=-1;
flag=t=0;
}
};
node a[N];
int e,n,m;
void insert(char s[],int t)
{
int i,k,p=0;
for(i=0;s[i];i++)
{
k=s[i]-'A';
if(a[p].next[k]==-1)
{
a[e].init();
a[p].next[k]=e++;
}
p=a[p].next[k];
}
a[p].flag=t;
}
queue<int> Q;
void build()
{
int i,j,k,p,q;
FOR0(i,26) if(a[0].next[i]!=-1)
{
Q.push(a[0].next[i]);
a[a[0].next[i]].fail=0;
}
while(!Q.empty())
{
k=Q.front();
Q.pop();
for(i=0;i<26;i++)
{
if(a[k].next[i]!=-1)
{
p=a[k].next[i];
q=a[k].fail;
Q.push(p);
while(q!=-1&&a[q].next[i]==-1) q=a[q].fail;
if(q!=-1&&a[q].next[i]!=-1) a[p].fail=a[q].next[i];
else a[p].fail=0;
}
}
}
}
char s[N],s1[N];
void reverse(char *s,int len)
{
int L=0,R=len-1;
while(L<R)
{
swap(s[L],s[R]);
L++;
R--;
}
}
void init()
{
int len=strlen(s),L=0,i,j,k,t;
FOR0(i,len)
{
if(s[i]>='A'&&s[i]<='Z') s1[L++]=s[i];
else if(s[i]=='[')
{
k=0;
j=i+1;
while(isdigit(s[j]))
{
k=k*10+s[j]-'0';
j++;
}
i=j+1;
FOR0(t,k) s1[L++]=s[j];
}
}
s1[L]=0;
}
int hash[255];
void find(char *s)
{
int i,k,p=0,pre;
for(i=0;s[i];i++)
{
k=s[i]-'A';
while(p>=0&&a[p].next[k]==-1) p=a[p].fail;
if(p==-1)
{
p=0;
continue;
}
pre=p=a[p].next[k];
while(pre>=0&&a[pre].t==0)
{
a[pre].t=1;
hash[a[pre].flag]=1;
pre=a[pre].fail;
}
}
}
int main()
{
int C;
RD(C);
while(C--)
{
scanf("%d",&n);
a[0].init();e=1;
int i;
FOR1(i,n) RD(s),insert(s,i);
build();
RD(s);
init();
clr(hash,0);
find(s1);
reverse(s1,strlen(s1));
find(s1);
int ans=0;
FOR1(i,n) ans+=hash[i];
PR(ans);
}
return 0;
}