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 ...
随机推荐
- poj1159 【LCS】
思路: 滚动数组; 贴一发挫code- #include <iostream> #include <cstdio> #include <string.h> #inc ...
- Ascall码的故事
没事发个ascall码表,二进制值得研究呦 sub al,30h; and al,00001111b ;字符ascall转数字or al,00110000b; sub al,32; and al,11 ...
- EasyUI 前台开发的好助手
今天用了下EASY ui 确实经典,前端开发利器啊
- 浅谈算法——KMP
KMP是啥?KMP当然是KMPlayer的简称啦 KMP算法是用来解决字符串匹配的一种算法,由D.E.Knuth.J.H.Morris和V.R.Pratt同时发现,然后它可以用来干啥呢?我们上个例题: ...
- BZOJ4653(区间离散化+线段树+决策单调尺取)
写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...
- Maximal Area Quadrilateral CodeForces - 340B || 三点坐标求三角形面积
Maximal Area Quadrilateral CodeForces - 340B 三点坐标求三角形面积(可以带正负,表示向量/点的不同相对位置): http://www.cnblogs.com ...
- h5-24-百度地图-地址解析
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- oracle 查看未关闭连接
查看连接状态.问题电脑等信息: select sid,serial#,username,program,machine,status from v$session; 2.查看sql; select ...
- C++ <string> 里面的size_type
string::size_type string的 str.size() 返回值是一个unsigned,实际上返回的是size_type类型的值. string类和其他的大多数标准库类型都定义了几套配 ...
- POST 传参
$http.post("../jzgCar_listAllJzgCar.do?data={parentId:"+value+"}") value 是参数,都是双 ...