hdu2222

我不想说啥了。。。T T

#include<iostream>
#include<string>
#include<deque>
using namespace std;
const char ax='a';
const int maxn=500004;
const int maxc=55;
const int maxx=1000005;
char ss[maxc];
char a[maxx];
struct tree
{
int has;
bool yes;
tree* p[26];
int h;
tree* out;
tree* pre;
tree* fail;
}node[maxn],*head,*temp,*now;


string aa,b;
int T,N,x;
int sum,ncnt;
deque<tree*>ptre;


inline tree* creat()
{
for(int i=0;i<26;++i)
{
node[ncnt].p[i]=NULL;
}
node[ncnt].has=0;
node[ncnt].yes=false;
node[ncnt].pre = node[ncnt].out = node[ncnt].fail = NULL;
return &node[ncnt++];
}

inline void insert()
{
now=head;
for(int i=0;i<b.length();++i)
{
x=b[i]-ax;
if(now->p[x]==NULL)
{
now->p[x]=creat();
now->p[x]->pre=now;
now->p[x]->h=x;
}
now=now->p[x];
}
now->has++;
return ;
}


void init()
{
ptre.clear();
for(int i=0;i<26;++i)
{
if(head->p[i]!=NULL)
{
ptre.push_front(head->p[i]);
}
}
while(!ptre.empty())
{
now=ptre.back();
for(int i=0;i<26;++i)
{
if(now->p[i]!=NULL)
{
ptre.push_front(now->p[i]);
}
}
temp=now->pre;
while(true)
{
if(NULL==temp->fail)
{
now->fail=head;
break;
}
else
{
temp=temp->fail;
if(temp->p[now->h]!=NULL)
{
now->fail=temp->p[now->h];
break;
}
}
}
temp=now->fail;
if(temp->has)
{
now->out=temp;
now->yes=true;
}
else
{
now->out=temp->out;
now->yes=temp->yes;
}
ptre.pop_back();
}
return ;
}


void build_next()
{
ptre.clear();
for(int i=0;i<26;++i)
{
if(head->p[i]!=NULL)
{
ptre.push_front(head->p[i]);
}
else
{
head->p[i]=head;
}
}
while(!ptre.empty())
{
now=ptre.back();
for(int i=0;i<26;i++)
{
if(now->p[i]!=NULL)
{
ptre.push_front(now->p[i]);
}
else
{
temp=now;
while(true)
{
if(temp->fail->p[i]!=NULL)
{
now->p[i]=temp->fail->p[i];
break;
}
else
{
temp=temp->fail;
if(temp==head)
{
now->p[i]=head;
break;
}
}
}
}
}
ptre.pop_back();
}
return ;
}


void calculate()
{
now=head;
for(int i=0;a[i];++i)
{
x=a[i]-ax;
now=now->p[x];
if(now->has)
{
sum+=now->has;
now->has=0;
}
if(now->yes)
{
temp=now->out;
now->yes=false;
while(true)
{
if(temp->has)
{
sum+=temp->has;
temp->has=0;
}
if(temp->yes)
{
temp->yes=false;
temp=temp->out;
continue;
}
else
{
break;
}
}
}
}
return ;
}


int main()
{
scanf("%d",&T);
for(int tt=1;tt<=T;++tt)
{
scanf("%d",&N);
ncnt=0;
head=creat();
for(int i=1;i<=N;++i)
{
scanf("%s",ss);
b=ss;
insert();
}
scanf("%s",a);
init();
build_next();
sum=0;
calculate();
printf("%d\n",sum);
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值