[2015hdu多校联赛补题]hdu5384 Danganronpa
2015-08-13 17:26
483 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384
题意:函数f(A, B)定义:A、B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2 f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的
View Code
题意:函数f(A, B)定义:A、B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2 f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的
/* * Problem: hdu5384 Danganronpa * Author: SHJWUDP * Created Time: 2015/8/13 星期四 14:38:23 * File Name: 1006.cpp * State: Accepted * Memo: ac自动机 */ #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int MaxA=1e5+7; const int MaxB=7e5+7; const int SIGMA_SIZE=27; struct AhoCorasickAutomata { int ch[MaxB][SIGMA_SIZE]; int val[MaxB]; int sz; int f[MaxB], last[MaxB]; int newNode() { memset(ch[sz], 0, sizeof(ch[sz])); val[sz]=0; return sz++; } void init() { sz=0; newNode(); } int id(char c) { return c-'a'; } void insert(char* p) { int u=0; while(*p) { int c=id(*p++); if(!ch[u][c]) ch[u][c]=newNode(); u=ch[u][c]; } val[u]++; } void getFail() { queue<int> Q; f[0]=0; for(int c=0; c<SIGMA_SIZE; c++) { int u=ch[0][c]; if(u) { f[u]=0; Q.push(u); last[u]=0; } } while(!Q.empty()) { int r=Q.front(); Q.pop(); for(int c=0; c<SIGMA_SIZE; c++) { int u=ch[r][c]; if(!u) { ch[r][c]=ch[f[r]][c]; continue; } Q.push(u); int v=f[r]; while(v && !ch[v][c]) v=f[v]; f[u]=ch[v][c]; last[u]=val[f[u]]?f[u]:last[f[u]]; } } } long long dealAns(int u) { long long res=0; while(u) { res+=val[u]; // val[u]=0; u=last[u]; } return res; } void find(char * T, long long * ans) { int u=0; int pos=1; long long sum=0, ltsum=0; for(int i=0; T[i]; i++) { int c=id(T[i]); u=ch[u][c]; if(val[u]) sum+=dealAns(u); else if(last[u]) sum+=dealAns(last[u]); if(T[i]=='z'+1) { ans[pos++]+=sum-ltsum; ltsum=sum; } } } } ac; int n, m; char str[MaxB]; long long ans[MaxA]; char gogogo[MaxA]; int main() { #ifndef ONLINE_JUDGE freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); int len=0; for(int i=0; i<n; i++) { scanf("%s", str+len); while(str[len]) len++; str[len++]='z'+1; } str[len]='\0'; ac.init(); for(int i=0; i<m; i++) { scanf("%s", gogogo); ac.insert(gogogo); } ac.getFail(); memset(ans, 0, sizeof(ans)); ac.find(str, ans); for(int i=1; i<=n; i++) { printf("%I64d\n", ans[i]); } } return 0; }
View Code
相关文章推荐
- limesurvey 权限插件开发 - 接入第三方的用户系统
- Flip Game
- poj 2823(单调队列)
- 2440启动代码分析
- C++ primer 【笔记】关联容器 set
- Linux学习笔记---文件解压缩命令---gzip ==
- iOS每日一记之---------改变Btn点击时的背景颜色
- 不同.net版本实现单点登录
- Web开发基础知识
- HDU 1251 统计难题 trie树
- Centos7安装配置Mongodb3
- 一个计时器, 点击按钮 让他 停一会, 5s后继续自动运行
- iNOC产品部-杨辉三角的变形
- Prime Path(POJ--3126
- 按返回键的时候实现按home键的效果
- KMP算法模板
- 在本地机器上能访问tomcat,远程机器访问不了的解决方法
- sql字符串累加
- GridView控件实现数据的修改(第9节)
- java GUI(UI创建与监听机制)