Spoj8093 Sevenk Love Oimaster
题解:
对于所有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的更多相关文章
- BZOJ2780:[SPOJ8093]Sevenk Love Oimaster(广义SAM)
Description Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXu ...
- BZOJ.2780.[SPOJ8093]Sevenk Love Oimaster(广义后缀自动机)
题目链接 \(Description\) 给定n个模式串,多次询问一个串在多少个模式串中出现过.(字符集为26个小写字母) \(Solution\) 对每个询问串进行匹配最终会达到一个节点,我们需要得 ...
- [BZOJ2780][SPOJ8093]Sevenk Love Oimaster
bzoj luogu 题面 给定n个模板串,以及m个查询串. 依次查询每一个查询串是多少个模板串的子串. sol 广义后缀自动机裸题? 先建出\(SAM\),然后记录一下每个节点分别在多少个模板串里出 ...
- [bzoj2780][Spoj8093]Sevenk Love Oimaster_广义后缀自动机
Sevenk Love Oimaster bzoj-2780 Spoj-8093 题目大意:给定$n$个大串和$m$次询问,每次给出一个字符串$s$询问在多少个大串中出现过. 注释:$1\le n\l ...
- BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )
全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...
- BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]
JZPGYZ - Sevenk Love Oimaster Oimaster and sevenk love each other. But recently,sevenk hea ...
- SP8093 JZPGYZ - Sevenk Love Oimaster 解题报告
SP8093 JZPGYZ - Sevenk Love Oimaster 题目大意 给定\(n(n\le 10000)\)个模板串,以及\(m(m\le 60000)\)个查询串(模板串总长\(\le ...
- 【BZOJ2780】【SPOJ】Sevenk Love Oimaster(后缀自动机)
[BZOJ2780][SPOJ]Sevenk Love Oimaster(后缀自动机) 题面 BZOJ 洛谷 题解 裸的广义后缀自动机??? 建立广义后缀自动机建立出来之后算一下每个节点被几个串给包括 ...
- 【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 广义后缀自动机
[BZOJ2780][Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each other. But r ...
随机推荐
- 洛谷 - P2293 - 高精度开根 - 高精度
https://www.luogu.org/problemnew/show/P2293 要求求出给定高精度整数的非负根取整的结果. 还有神仙用Python的浮点pow运算骗到不少分的. 唉! 那么我们 ...
- CodeForces 615C
题意: 给定两个字符串s1,s2利用s1去构造s2,s1有无限个,可以翻转,你最少要用几个s1才能构造s2.输出每一次使用的s1的有效区间. 伪思路: 据说是暴力就能过的题目.然而自己就是暴力差,模拟 ...
- hdoj1528【二分匹配】
题意: 在一幅扑克牌里,有两个人在比大小,第二个人最多能赢第一个人几张牌. 思路: 这道题目用一下二分匹配还是很明显的. 那么就是建图似乎要麻烦一下,但还是很方便的.将扑克牌一次进行编号,然后牌面比他 ...
- 洛谷P2585 [ZJOI2006]三色二叉树(树形dp)
传送门 设$dp[u][i]$表示点$u$颜色为$i$时最多(最少)的绿点个数(这里用$0$表示绿点) 然后直接用树形dp就可以了 记得把情况讨论清楚 //minamoto #include<b ...
- locate的基本用法
一.工作原理 1. locate是通过读取一个或多个由updatedb命令生成的数据库来查找文件的,而updatedb由计划任务程序cron每天运行来更新缺省的数据库(/var/lib/mlocate ...
- tyvj 1391 走廊泼水节【最小生成树】By cellur925
题目传送门 题意简化:给你一棵树,要求你加边使它成为完全图(任意两点间均有一边相连) ,满足原来的树是这个图的最小生成树.求加边的价值最小是多少. 考虑Kruskal的过程,我们每次找一条最短的,两边 ...
- VMware安装Centos 7,网络连接问题以及解决方案
转自: https://www.cnblogs.com/owaowa/p/6123902.html 在这里表示万分感谢 在使用CentOS虚拟机后,出现了无法上网的情况,使用主机ping虚机地址可以p ...
- 项目中java异常处理
一.java异常类介绍. Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类. 有一篇比较好的blog ...
- 为什么使用Stylus
CSS预处理器的出现大大的提高了前端开发的效率和逼格,它让CSS可编程化.LESS和Sass/SCSS是两种最为常见的预处理器,拥有大量的用户基数,数目庞杂的第三方库.然而,还有一种预处理器并未引起足 ...
- 跟我一起玩Win32开发(19):浏览和打开文件
在应用程序中,我们很经常要实现的功能,是Open文件或保存文件对话框,让用户来选择一个或N个文件.本文我将介绍两种思路,第一种方法较为复杂,第二种方法较为简单. 方法一:老规矩 这是一种传统方法,使用 ...