【题目链接】 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. QF——OC字符串

    OC中的字符串: C中没有字符串类型,用字符数组和指针代替. OC中引入了字符串类型,它包括NSString 和 NSMutableString两种 NSString是不可变的,已经初始化便不能更改: ...

  2. Android 调用系统通讯录

    这个过程有三步:1)许可向你的应用程序的manifest中添加读取通讯录数据的许可  <uses-permission android:name="android.permission ...

  3. APP分享抓取网页图片

    var getShareImages = { defaultimg:"defaultimg.png", _allImgs:null, init:function(){ getSha ...

  4. seajs 学习笔记

    seajs的作者是玉伯,具体好处优点等详见官方网址 介绍 1 模块定义define define(function(require,exports,module){ //require 引入需要的模块 ...

  5. 初识Sencha Touch:面板Panel

    HTML代码: <!doctype html> <html> <head> <meta charset="utf-8"> <t ...

  6. WIX 学习笔记 - 2 第一个WIX 项目 HelloWIX

    程序员们都非常熟悉 Hello World!,基本上所有的语言书都以打印一个 Hello World! 作为第一个代码示例. 我们也要发扬代码界的优良传统,使用 Hello WIX! 作为我们的入门示 ...

  7. ViewTreeObserver简介

    Android ViewTreeObserver简介 一.结构 public final class ViewTreeObserver extends Object java.lang.Object ...

  8. JAVA 中的RMI是什么

    RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台 ...

  9. 数据库CRUD操作

    CRUD操作: C:create 增加数据: insert into 表名 values('N001','汉族') 普通 insert into 表名 values('','','') 如果有自增长列 ...

  10. 什么时候css会见less

    在一定程度上,css不能被视为一个节目.虽然和其他语言,它有自己的规范.编码,但它的笨拙实在让我失望. 不喜欢css是由于不管怎么优化代码.项目大到一定程序后.都会看上去一团乱.并且有时候一个bug的 ...