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; }
相关文章推荐
- [数据结构]线性结构——队列
- COJ 0979 WZJ的数据结构(负二十一)
- 数据结构——九大排序算法二
- 数据结构——九大排序算法一
- 数据结构——算法(030)(在所有小写字母串大写字母前排)
- POJ 1984 Navigation Nightmare (数据结构-并检查集合)
- java数据结构和算法------索引查找
- 数据结构(五)---图:
- java数据结构和算法------哈希查找
- java中的数据结构
- Binder学习一——基础数据结构
- PAT《数据结构学习与实验指导》实验项目集 2-07
- MySQL索引背后的数据结构及算法原理
- java数据结构和算法------折半查找
- 算法一:排序和数据结构体
- 《算法导论》 — Chapter 10 基本数据结构
- 《算法导论》 — Chapter 10 基本数据结构
- java数据结构和算法------顺序查找
- 数据结构基础 之 二叉搜索树的思想与实现
- java数据结构和算法------希尔排序