bzoj 3172 后缀数组|AC自动机
后缀数组或者AC自动机都可以,模板题。
/**************************************************************
Problem: 3172
User: BLADEVIL
Language: C++
Result: Accepted
Time:424 ms
Memory:34260 kb
****************************************************************/ //By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 2000010
#define maxm 300 using namespace std; struct node{
int cnt;
node *fail,*child[];
node(){
cnt=; fail=NULL;
memset(child,,sizeof child);
}
} *que[maxn],*root=new(node),*w[maxm]; int n; int main(){
scanf("%d",&n);
for (int i=;i<=n;i++){
char c[maxn];
scanf("%s",&c);
int len=strlen(c);
node *t=root;
for (int j=;j<len;j++){
if (!t->child[c[j]-'a']) t->child[c[j]-'a']=new(node);
t=t->child[c[j]-'a']; t->cnt++;
}
w[i]=t;
}
int h=,t=;
root->fail=root; que[]=root;
while (h<t){
node *u=que[++h];
for (int i=;i<;i++) if (u->child[i]){
que[++t]=u->child[i];
node *v=u->fail;
que[t]->fail=v->child[i]&&v->child[i]!=que[t]?v->child[i]:root;
} else u->child[i]=u->fail->child[i];
}
for (int i=t;i;i--) que[i]->fail->cnt+=que[i]->cnt;
for (int i=;i<=n;i++) printf("%d\n",w[i]->cnt);
return ;
}
/**************************************************************
Problem: 3172
User: BLADEVIL
Language: C++
Result: Accepted
Time:6660 ms
Memory:107360 kb
****************************************************************/
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1001000
#define maxm 300 using namespace std; int n,len;
char s[maxn];
int sa[maxn],tsa[maxn],rk[maxn],trk[maxn],sum[maxn],h[maxn];
int w[maxn][];
int adr[maxm],len_s[maxm]; inline void getsa(int j) {
for (int i=;i<=len;i++) sum[i]=;
for (int i=;i<=len;i++) sum[rk[i+j]]++;
for (int i=;i<=len;i++) sum[i]+=sum[i-];
for (int i=len;i;i--) tsa[sum[rk[i+j]]--]=i; for (int i=;i<=len;i++) sum[i]=;
for (int i=;i<=len;i++) sum[rk[i]]++;
for (int i=;i<=len;i++) sum[i]+=sum[i-];
for (int i=len;i;i--) sa[sum[rk[tsa[i]]]--]=tsa[i];
} inline int query(int l,int r) {
int i,j;
for (i=,j=;(j<<)<=r-l+;j<<=,i++) ;
return min(w[l][i],w[r-j+][i]);
} int main() {
scanf("%d",&n); len=;
for (int i=;i<=n;i++) {
scanf("%s",s+len+);
adr[i]=len+;
len=strlen(s+);
s[++len]='^';
len_s[i]=len-adr[i];
}
//for (int i=1;i<=len;i++) printf("%c",s[i]); printf("\n");
for (int i=;i<=len;i++) sum[s[i]]++;
for (int i=;i<=;i++) sum[i]+=sum[i-];
for (int i=len;i;i--) sa[sum[s[i]]--]=i;
rk[sa[]]=;
for (int i=,p=;i<=len;i++) {
if (s[sa[i]]!=s[sa[i-]]) p++;
rk[sa[i]]=p;
}
for (int j=;j<=len;j<<=) {
getsa(j);
trk[sa[]]=;
for (int i=,p=;i<=len;i++) {
if (rk[sa[i]]!=rk[sa[i-]]||rk[sa[i]+j]!=rk[sa[i-]+j]) p++;
trk[sa[i]]=p;
}
for (int i=;i<=len;i++) rk[i]=trk[i];
}
for (int i=,j=;i<=len;i++) {
if (rk[i]==) continue;
while (i+j<=len&&sa[rk[i]-]+j<=len&&s[i+j]==s[sa[rk[i]-]+j]) j++;
h[rk[i]]=j;
if (j) j--;
}
//for (int i=1;i<=len;i++) printf("%d ",sa[i]); printf("\n");
//for (int i=1;i<=len;i++) printf("%d ",h[i]); printf("\n");
memset(w,,sizeof w);
for (int i=;i<=len;i++) w[i][]=h[i];
for (int j=,k=;j<;j++,k<<=)
for (int i=;i<=len;i++)
if (i+k<=len) w[i][j]=min(w[i][j-],w[i+k][j-]);
//for (int i=1;i<=len;i++) printf("%d ",w[i][2]); printf("\n");
//printf("%d\n",query(5,8));
//printf("%d\n",rk[6]);
for (int i=;i<=n;i++) {
int l=,r=rk[adr[i]],mid,left=rk[adr[i]],right=rk[adr[i]];
while (l<=r) {
mid=l+r>>;
if (query(mid+,rk[adr[i]])>=len_s[i])
left=mid,r=mid-; else l=mid+;
}
l=rk[adr[i]],r=len;
while (l<=r) {
mid=l+r>>;
if (query(rk[adr[i]]+,mid)>=len_s[i])
right=mid,l=mid+; else r=mid-;
}
printf("%d\n",right-left+);
}
return ;
}
bzoj 3172 后缀数组|AC自动机的更多相关文章
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ 3172 单词(ac自动机)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3172 题意:给出n个单词.输出每个单词在所有单词中一共出现多少次? 思路:首先将所有单词 ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树
题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...
- 【字符串】BZOJ上面几个AC自动机求最为字串出现次数的题目
(一下只供自己复习用,目的是对比这几个题,所以写得不详细.需要细节的可以参考其他博主) [BZOJ3172:单词] 题目: 某人读论文,一篇论文是由许多(N)单词组成.但他发现一个单词会在论文中出现很 ...
- BZOJ.2938.[POI2000]病毒(AC自动机)
题目链接 \(Description\) 给n个模式串,问是否存在长度无限的主串,使得任何一个模式串都没有在主串中出现. \(Solution\) 先建AC自动机. 假设我们有了一个无限长的安全代码, ...
- bzoj 1398: 寻找主人 AC自动机+最小表示法
题目大意: 给定两个序列判断是否循环同构,若循环同构则输出最小表示 题解: 因为没有样例输入输出,一开始没看到要求输出最小表示 Wa一大页. 但不得不说bzoj还是挺高效的: 赞一个 XD.jpg 判 ...
- bzoj 3881: [Coci2015]Divljak AC自动机
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3881 题解: 这道题我想出了三种做法,不过只有最后一种能过. 第一种: 首先我们把所有的 ...
- BZOJ 4516 后缀数组+ST+set
写了一半 没了啊啊啊 重新写的 思路: 先不考虑后缀自动机 (我不会啊) 那这道题只能用后缀数组了 先把原串倒一下 后缀->前缀 相当于每回在前面加了一个字母 求不同的子串个数 首先 正常的求子 ...
随机推荐
- Unity2D之让土豆人动起来
Unity2D功能 Unity3D最新的4.3版本,其中最大的新功能就是这个2D工具了.我这里简单介绍一下这个2D工具是怎样使用的. 首先,在我们创建项目的时候,面板上面多了一个2d和3d的选择,这两 ...
- SQL 第一范式、第二范式、第三范式、BCNF
作者 : Dolphin 原文地址: http://blog.csdn.net/qingdujun/article/details/27365979 一.第一范式 1NF 要求:每一个分量必须是不可分 ...
- 内联(行级)元素不能设置margin-top
内联(行级)元素 不能设置宽高,但padding属性可以设置,需要注意的是行级元素不能设置margin-top和margin-bottom属性,但可以设置margin-left和margin-righ ...
- 分布式监控系统Zabbix-3.0.3-完整安装记录(5)-邮件报警部署
前面几篇陆续介绍了zabbix3.0.3监控系统的部署和监控项配置,今天这里分享下zabbix3.0.3的邮件报警的配置过程~由于采用sendmail发送邮件,常常会被认为是垃圾邮件被拒,所以不推荐这 ...
- project和task
projects和tasks是Gradle中最重要的两个概念 任何一个Gradle构建狗屎一个或多个projects的组成.每个project包括许多可构建组成部分 什么是 project ? 一个j ...
- 【转】【WPF】资源读取 URI
一开始看到WPF里面经常用如下语句来构造资源文件Uri: Uri uri = new Uri("/AssemblyName;component/image.png"); 我还以为这 ...
- 一个按钮,如果5分钟内点击再次点击给予提示操作频繁,在JS里可以这样写
很简单. 但是,如果你要离开这个页面再进来, 就没办法限制了. 除非用cookie 储存状态 给个示例 var isLock = flase; //定义全局变量 按钮点击事件: if(isLock){ ...
- matlab中findstr,strfind,strcmp,strncmp区别与联系
在Matlab中,这几个函数区分如下: (以下默认S1和S2是字符串,同样也适用于cell细胞类型数据,也就是循环对cell中每个元素分别判断即可.) findstr(S1,S2):寻找是否有S1和S ...
- C#脚本引擎 CS-Script 之(二)——性能评测
以下以一个简单的HelloWord程序为例,来分析csscript脚本引擎的性能. class HelloWorld { public void SayHello() { Console.WriteL ...
- [CareerCup] 13.3 Virtual Functions 虚函数
13.3 How do virtual functions work in C++? 这道题问我们虚函数在C++中的工作原理.虚函数的工作机制主要依赖于虚表格vtable,即Virtual Table ...