您的位置:首页 > 理论基础 > 数据结构算法

COJ 0999 WZJ的数据结构(负一)

2015-07-07 20:45 615 查看
WZJ的数据结构(负一)
难度级别:D; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述
输入N个模板串Pi和文本串T,输出每个模板串Pi在T中出现了多少次。
输入
第一行为一个正整数N。
接下来N行为Pi。
最后一行为T

输出

输出N行,第i行为模板串Pi在T中出现的次数。

输入示例

5
a
ab
ba
aba
a
ababababa

输出示例

5
4
4
4
5

其他说明

1<=sigma(|Pi|)<=1000000
1<=|T|<=1000000
保证Pi与T只由小写字母'a'或'b'组成

题解:感人至深!

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=1000000+10,inf=-1u>>1,sig=2,maxnode=maxn;
struct node{node*tx[sig],*fail;int x;node(){x=0;}}ac[maxnode],*nodecnt=ac,*root=nodecnt++;
struct ted{int x,y;ted*nxt;}adj[maxn],*ms=adj,*fch[maxn],adj2[maxn],*ms2=adj2,*fch2[maxn];
void add(int x,int v){*ms=(ted){x,v,fch[x]};fch[x]=ms++;return;}
void add2(int x,int y){*ms2=(ted){x,y,fch2[x]};fch2[x]=ms2++;return;}
int num[maxn],ans[maxn];
void insert(char*s,int v){
node*x=root;
for(int i=0;s[i];i++){
int c=s[i]-'a';
if(!x->tx[c]) x->tx[c]=nodecnt++;
x=x->tx[c];
} add(x-ac,v);return;
}
void getfail(){
queue<node*>Q;for(int c=0;c<sig;c++)if(root->tx[c])Q.push(root->tx[c]),root->tx[c]->fail=root;
while(!Q.empty()){
node*x=Q.front();Q.pop();
for(int c=0;c<sig;c++)if(x->tx[c]){
node*p=x->fail;while(p&&!p->tx[c])p=p->fail;if(!p)p=root;
x->tx[c]->fail=p->tx[c]?p->tx[c]:root;Q.push(x->tx[c]);
}
} return;
}
void dfs(node*x){
for(ted*e=fch2[x-ac];e;e=e->nxt) dfs(e->y+ac),num[x-ac]+=num[e->y];
}
int query(char*s){
for(int i=1;i<=nodecnt-ac-1;i++) add2(ac[i].fail-ac,i);
node*x=root;
for(int i=0;s[i];i++){
int c=s[i]-'a';
while(x&&!x->tx[c]) x=x->fail;if(!x)x=root;
x=x->tx[c]?x->tx[c]:root;num[x-ac]++;
} dfs(root);
for(int i=nodecnt-ac-1;i;i--)
for(ted*e=fch[i];e;e=e->nxt)
ans[e->y]=num[i];
}
inline int read(){
int x=0,sig=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
return x*=sig;
}
inline void write(int x){
if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x;
int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
}
char s[maxn];
int n;
void init(){
n=read();
for(int i=1;i<=n;i++) scanf("%s",s),insert(s,i);
getfail();
scanf("%s",s);query(s);
for(int i=1;i<=n;i++) write(ans[i]),ENT;
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){
init();work();print();return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: