题目描述

题解:

对于所有n串建广义后缀自动机。

(广义后缀自动机唯一区别就是每次将las附成1,并不需要在插入时特判)

建完后再建出parent树,然后用dfs序+树状数组搞区间不同种类。

其实就是HH的项链+广义后缀自动机。很水的。(虽然我调了半个晚上)

代码:

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100050
int n,q;
char s[];
int ic(char c)
{
if(c>='a'&&c<='z')return c-'a'+;
if(c>='A'&&c<='Z')return c-'A'+;
if(c>=''&&c<='')return c-''+;
if(c==',')return ;
if(c=='.')return ;
return ;
}
int tin[*N],tout[*N],tim,pla[*N];
struct SAM
{
struct node
{
int len,pre,trs[];
vector<int>v;
}p[*N];
int tot,las;
SAM(){tot=las=;}
void res(){las=;}
void insert(int c,int k)
{
int np,nq,lp,lq;
np = ++tot;
p[np].len = p[las].len+;
for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre)
p[lp].trs[c]=np;
if(!lp)p[np].pre = ;
else
{
lq = p[lp].trs[c];
if(p[lq].len == p[lp].len+)p[np].pre = lq;
else
{
nq = ++tot;
p[nq] = p[lq];
p[nq].len = p[lp].len+;
p[lq].pre = p[np].pre = nq;
while(p[lp].trs[c]==lq)
{
p[lp].trs[c]=nq;
lp=p[lp].pre;
}
}
}
las = np;
p[las].v.push_back(k);
}
int hed[*N],cnt;
struct EG
{
int to,nxt;
}e[*N];
void ae(int f,int t)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
hed[f] = cnt;
}
void dfs(int u)
{
tin[u]=++tim;pla[tim]=u;
for(int j=hed[u];j;j=e[j].nxt)dfs(e[j].to);
tout[u]=tim;
}
void build()
{
for(int i=;i<=tot;i++)
ae(p[i].pre,i);
dfs();
}
}sam;
int ans[],ct;
struct Pair
{
int l,r,id;
}qu[];
bool cmp(Pair a,Pair b)
{
return a.r<b.r;
}
int f[*N];
void up(int x,int d)
{
if(!x)return ;
while(x<=)f[x]+=d,x+=(x&(-x));
}
int down(int x)
{
if(!x)return ;
int ret = ;
while(x)ret+=f[x],x-=(x&(-x));
return ret;
}
int las[];
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
int len = strlen(s+);
sam.res();
for(int j=;j<=len;j++)
sam.insert(ic(s[j]),i);
}
sam.build();
for(int i=;i<=q;i++)
{
scanf("%s",s+);
int len = strlen(s+);
int u = ;
for(int j=;j<=len&&u;j++)
u=sam.p[u].trs[ic(s[j])];
if(u)
{
ct++;
qu[ct].l = tin[u];
qu[ct].r = tout[u];
qu[ct].id = i;
}
}
sort(qu+,qu++ct,cmp);
for(int k=,i=;i<=tim;i++)
{
for(int j=;j<sam.p[pla[i]].v.size();j++)
{
up(i,);
up(las[sam.p[pla[i]].v[j]],-);
las[sam.p[pla[i]].v[j]]=i;
}
int tmp = down(i);
for(;qu[k].r==i;k++)
ans[qu[k].id] = tmp - down(qu[k].l-);
}
for(int i=;i<=q;i++)
printf("%d\n",ans[i]);
return ;
}

Spoj8093 Sevenk Love Oimaster的更多相关文章

  1. BZOJ2780:[SPOJ8093]Sevenk Love Oimaster(广义SAM)

    Description Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXu ...

  2. BZOJ.2780.[SPOJ8093]Sevenk Love Oimaster(广义后缀自动机)

    题目链接 \(Description\) 给定n个模式串,多次询问一个串在多少个模式串中出现过.(字符集为26个小写字母) \(Solution\) 对每个询问串进行匹配最终会达到一个节点,我们需要得 ...

  3. [BZOJ2780][SPOJ8093]Sevenk Love Oimaster

    bzoj luogu 题面 给定n个模板串,以及m个查询串. 依次查询每一个查询串是多少个模板串的子串. sol 广义后缀自动机裸题? 先建出\(SAM\),然后记录一下每个节点分别在多少个模板串里出 ...

  4. [bzoj2780][Spoj8093]Sevenk Love Oimaster_广义后缀自动机

    Sevenk Love Oimaster bzoj-2780 Spoj-8093 题目大意:给定$n$个大串和$m$次询问,每次给出一个字符串$s$询问在多少个大串中出现过. 注释:$1\le n\l ...

  5. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )

    全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...

  6. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]

    JZPGYZ - Sevenk Love Oimaster     Oimaster and sevenk love each other.       But recently,sevenk hea ...

  7. SP8093 JZPGYZ - Sevenk Love Oimaster 解题报告

    SP8093 JZPGYZ - Sevenk Love Oimaster 题目大意 给定\(n(n\le 10000)\)个模板串,以及\(m(m\le 60000)\)个查询串(模板串总长\(\le ...

  8. 【BZOJ2780】【SPOJ】Sevenk Love Oimaster(后缀自动机)

    [BZOJ2780][SPOJ]Sevenk Love Oimaster(后缀自动机) 题面 BZOJ 洛谷 题解 裸的广义后缀自动机??? 建立广义后缀自动机建立出来之后算一下每个节点被几个串给包括 ...

  9. 【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 广义后缀自动机

    [BZOJ2780][Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each other.     But r ...

随机推荐

  1. hdoj1575【矩阵快速幂】

    题意:非常清晰! 直接搞吧. #include <iostream> #include <stdio.h> #include <string.h> #include ...

  2. Ironpython 安装numpy包

    http://pytools.codeplex.com/wikipage?title=NumPy%20and%20SciPy%20for%20.Net https://www.enthought.co ...

  3. P5167 xtq的神笔

    传送门 题解 倍增也好二分也好,果然复杂度只要和\(\log\)插上关系就没我啥事了-- 首先由一个显而易见然而我完全没有发现的结论,设\(calc(l,r)\)表示区间\([l,r]\)的\(or\ ...

  4. 基于 CODING 轻松搞定持续集成

    点击观看视频教程 带你一步一步搞定 CODING 持续集成 持续集成加速软件交付 持续集成这个概念是由 Grady Booch 在 1991 年首次提出,随后成为了 DevOps 的核心实践之一.持续 ...

  5. SOA架构设计和相关案例分析

    一.SOA概念 1.定义: SOA,是一个组件模型,面向服务的体系架构,它将应用程序的不同服务通过这些服务之间定义良好的接口和契约联系起来,不涉及底层编程接口和通讯模型.服务层是SOA的基础,可以直接 ...

  6. PopupWindow(1)简介

    PopupWindow有点类似于Dialog,相同点在于都是弹出窗口,并且都可以对其进行自定义显示,并且里面的监听组件,进行相应的操作,但它与Dialog又有很大的区别,PopupWindow只是弹出 ...

  7. python关于文件的一些记录

    1.文件打开: file("data.txt")或open("data.txt")注意不要漏了文件的后缀.(不加参数时,file为你默认为'r',reading ...

  8. 167 Two Sum II - Input array is sorted 两数之和 II - 输入有序数组

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数.函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2.请注意,返回的下标值(i ...

  9. AJPFX简述Context.startService()和Context.bindService

    Context.startService()和Context.bindService 服务不能自己运行,需要通过调用Context.startService()或Context.bindService ...

  10. SpringMvc返回@ResponseBody中文乱码

    使用SpringMvc的@ResponseBody返回指定数据的类型做为http体向外输出,在浏览器里返回的内容里有中文,会出现乱码,项目的编码.tomcat编码等都已设置成utf-8,如下返回的是一 ...