【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=4416

【题目大意】

  给出一个字符串,然后,给出一个字符串集合,问在该字符串中出现,且不在字符串集合中出现的子串总数。

【题解】

  将集合中所有的子串在自动机上跑,保存匹配到的位置的最长匹配,
  用于在parent树上计算每个位置的最长匹配,对于一个位置,
  如果不存在匹配,那么他对答案的贡献就是其value值,
  如果存在匹配且匹配长度小于其长度那么取其差作为答案的贡献。最后输出即可。

【代码】

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200005;
char s[N];
struct sam{
int p,q,np,nq,cnt,last,a[N][26],l[N],f[N];
sam(){cnt=0;last=++cnt;}
int val(int c){return l[c]-l[f[c]];}
void init(){
cnt=0;last=++cnt;
memset(a,0,sizeof(a));
memset(l,0,sizeof(l));
memset(f,0,sizeof(f));
memset(b,0,sizeof(b));
memset(u,0,sizeof(u));
}
void extend(int c){
p=last;np=last=++cnt;l[np]=l[p]+1;
while(!a[p][c]&&p)a[p][c]=np,p=f[p];
if(!p)f[np]=1;
else{
q=a[p][c];
if(l[p]+1==l[q])f[np]=q;
else{
nq=++cnt;l[nq]=l[p]+1;
memcpy(a[nq],a[q],sizeof(a[q]));
f[nq]=f[q]; f[np]=f[q]=nq;
while(a[p][c]==q)a[p][c]=nq,p=f[p];
}
}
}int b[N],x[N],n;
void build(){
scanf("%s",s+1);
int len=strlen(s+1);n=len;
for(int i=1;i<=len;i++)extend(s[i]-'a');
for(int i=1;i<=cnt;i++)b[l[i]]++;
for(int i=1;i<=len;i++)b[i]+=b[i-1];
for(int i=1;i<=cnt;i++)x[b[l[i]]--]=i;
}int u[N];
void doit(){
scanf("%s",s+1);
int p=1,len=strlen(s+1),tmp=0;
for(int i=1;i<=len;i++){
int c=s[i]-'a';
if(a[p][c])p=a[p][c],tmp++,u[p]=max(u[p],tmp);
else{
while(p&&!a[p][c])p=f[p];
if(!p)p=1,tmp=0;
else tmp=l[p]+1,p=a[p][c],u[p]=max(u[p],tmp);
}
}
}
void solve(){
long long ans=0;
for(int i=cnt;i;i--){
if(u[x[i]]){
u[f[x[i]]]=max(u[x[i]],u[f[x[i]]]);
if(u[x[i]]<l[x[i]])ans+=l[x[i]]-u[x[i]];
}else ans+=val(x[i]);
}printf("%I64d\n",ans);
}
}sam;
int T,n,cas=1;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
sam.init();
sam.build();
for(int i=1;i<=n;i++)sam.doit();
printf("Case %d: ",cas++);
sam.solve();
}return 0;
}

  

HDU 4416 Good Article Good sentence(后缀自动机)的更多相关文章

  1. [hdu 4416]Good Article Good sentence

    最近几天一直在做有关后缀自动机的题目 感觉似乎对后缀自动机越来越了解了呢!喵~ 这题还是让我受益颇多的,首先搞一个后缀自动机是妥妥的了 可是搞完之后呢? 我们来观察 step 这个变量,每个节点的 s ...

  2. [hdu4416 Good Article Good sentence]后缀自动机SAM

    题意:给出串A和串集合B={B1,B2,...,Bn},求串A的所有不同子串中不是B中任一串的子串的数目. 思路:把A和B中所有字符串依次拼接在一起,然后构造后缀自动机,计算每个状态的R集合元素的最大 ...

  3. HDOJ 4416 Good Article Good sentence

    题解转自:http://blog.csdn.net/dyx404514/article/details/8807440 2012杭州网络赛的一道题,后缀数组后缀自己主动机都行吧. 题目大意:给一个字符 ...

  4. HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)

    Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...

  5. HDU 5343 MZL's Circle Zhou 后缀自动机+DP

    MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. HDU 6208 The Dominator of Strings 后缀自动机

    The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...

  7. HDU 6194 string string string(后缀自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题目大意] 给出一个字符串求其出现恰好k次的子串数量 [题解] 对串建立AC自 ...

  8. HDU 4416 (后缀自动机)

    HDU 4416 Good Article Good sentence Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现. Solution :首先对所有的T串建立后缀自 ...

  9. BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机 性质

    http://www.lydsy.com/JudgeOnline/problem.php?id=4516 http://blog.csdn.net/doyouseeman/article/detail ...

随机推荐

  1. mysql--自动增长

    create table teacher( t_id int primary key auto_increment, #auto_increment 自动增长 需要整型,还需要索引 t_name va ...

  2. 2 kNN-K-Nearest Neighbors algorithm k邻近算法(二)

    2.3 示例:手写识别系统 2.3 .1 准备数据:将图像转换为测试向量 训练样本:trainingDigits 2000个例子,每个数字大约200个样本 测试数据:testDigits 大约900个 ...

  3. 11.java.lang.ArrayStoreException

    java.lang.ArrayStoreException 数组存储异常 当试图将类型不兼容类型的对象存入一个Object[]数组时将引发异常 Object[] obj = new String[3] ...

  4. Delphi下TLabel鼠标MouseEnter、MouseLeave更改颜色失灵

    在Delphi 7下,如果想在鼠标MouseEnter.MouseLeave的时候改变TLabel自身的颜色,很多人可能会采用 Label.Color := clRed;这样的方式来实现,我当初也是一 ...

  5. VC++2008 用空工程创建 DLL

    VC++2008 用空工程创建 DLL 一.创建 DLL 工程项目: 1)点击菜单[File] -> [New] -> [Project...] 弹出 “New Project” 对话框: ...

  6. Sequence operation(线段树区间多种操作)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. android开发利器--站在巨人肩膀上前行

    本文主要介绍有助于android开发的三方平台和站点. 一:开发阶段 1:SVN(一个开放源码的版本号控制系统) 团队开发没有server,代码管理就没那么方便了,推荐taocode阿里开源站点,方便 ...

  8. 经常使用的DB2命令(2)

    catalog数据库: catalog indirect: db2 catalog database on /db2sys[dir_name] catalog remote:    db2 catal ...

  9. 一个SQL update语句

    须要每隔一段时间选取最老的商户更新时间戳: update DP_Shop set DP_Shop.LastDate = now() where DP_Shop.ShopId in (select Sh ...

  10. oracle超过最大游标数异常分析(转贴)

    问题描述 Oracle 使用 OPEN_CURSORS 参数指定一个会话一次最多可以打开的游标的数量.超过此数量时,Oracle 将报告 ORA-01000 错误.当此错误传播到 WebLogic S ...