BZOJ 2780 Sevenk Love Oimaster (后缀自动机+树状数组+dfs序+离线)
题目大意:
给你$n$个大串和$m$个询问,每次给出一个字符串$s$询问在多少个大串中出现过
好神的一道题
对$n$个大串建出广义$SAM$,建出$parent$树
把字符串$s$放到$SAM$里跑,找到能表示字符串$s$的节点$x$
问题转化为在$parent$树中,$x$节点的子树内,有多少个编号不同的$endpos$节点
把树拍扁,转化为$dfs$序
不就是在序列上跑HH的项链么,离线树状数组维护一下就好
一个节点可能有多个不同串$endpos$标记,用$vector$存一下串的编号就行了
注意索引不要写错,不要把数组开小了
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 105000
#define S1 (N1<<1)
#define T1 (N1<<2)
#define ll long long
#define uint unsigned int
#define rint register int
#define il inline
#define inf 0x3f3f3f3f
#define idx(X) (X-'a')
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} int n,m,len,tot;
char str[N1];
struct Edge{
int to[T1],nxt[T1],head[T1],cte;
void ae(int u,int v){
cte++;to[cte]=v;nxt[cte]=head[u],head[u]=cte;}
}E,Q;
struct BIT{
int sum[T1],ma;
void upd(int x,int w){
for(int i=x;i<=ma;i+=(i&(-i)))
sum[i]+=w;}
int query(int x){
int ans=;
for(int i=x;i>;i-=(i&(-i)))
ans+=sum[i];
return ans;}
}b;
namespace SAM{
int trs[S1][],pre[S1],dep[S1],la;
vector<int>ed[S1];
void init(){tot=la=;}
void reduct(){la=;}
void insert(int x,int id)
{
int p=la,q,np=++tot,nq;la=np;
dep[np]=dep[p]+;
ed[np].push_back(id);
for(;p&&!trs[p][x];p=pre[p]) trs[p][x]=np;
if(!p) pre[np]=;
else{
q=trs[p][x];
if(dep[q]==dep[p]+) pre[np]=q;
else{
pre[nq=++tot]=pre[q];
pre[q]=pre[np]=nq;
dep[nq]=dep[p]+;
memcpy(trs[nq],trs[q],sizeof(trs[q]));
for(;p&&trs[p][x]==q;p=pre[p]) trs[p][x]=nq;
}
}
}
void Build_Edge()
{
for(int i=;i<=tot;i++)
E.ae(pre[i],i);
}
int find(char *str,int L)
{
int x=;
for(int i=;i<=L;i++){
x=trs[x][idx(str[i])];
if(!x) return ;
}return x;
}
};
namespace Seq{
int st[T1],ed[T1],to[T1],ans[T1],la[T1],cnt;
void dfs1(int x)
{
st[x]=++cnt;
for(int j=E.head[x];j;j=E.nxt[j])
dfs1(E.to[j]);
ed[x]=++cnt;
to[cnt]=x;
}
void solve()
{
dfs1();
b.ma=cnt;
int x,v;
for(int i=;i<=m;i++)
{
scanf("%s",str+);
len=strlen(str+);
x=SAM::find(str,len);
if(x) Q.ae(ed[x],i);
}
for(int i=;i<=cnt;i++)
{
x=to[i];
for(int j=;j<SAM::ed[x].size();j++)
{
v=SAM::ed[x][j];
if(!la[v]) b.upd(i,),la[v]=i;
else b.upd(la[v],-),la[v]=i,b.upd(i,);
}
for(int j=Q.head[i];j;j=Q.nxt[j])
{
v=Q.to[j];
ans[v]=b.query(ed[x])-b.query(st[x]);
}
}
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
} }; int main()
{
//freopen("t2.in","r",stdin);
scanf("%d%d",&n,&m);
SAM::init();
for(int i=;i<=n;i++)
{
scanf("%s",str+);
len=strlen(str+);
for(int j=;j<=len;j++)
SAM::insert(idx(str[j]),i);
SAM::reduct();
}
SAM::Build_Edge();
Seq::solve();
return ;
}
BZOJ 2780 Sevenk Love Oimaster (后缀自动机+树状数组+dfs序+离线)的更多相关文章
- luogu SP8093 后缀自动机+树状数组+dfs序
这题解法很多,简单说几个: 1. 线段树合并,时间复杂度是 $O(nlog^2n)$ 的. 2. 暴力跳 $fail,$ 时间复杂度 $O(n\sqrt n),$ 比较暴力. 3. 建立后缀树后在 $ ...
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)
题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3881 [Coci2015]Divljak(AC自动机+树状数组)
建立AC自动机然后,加入一个串之后考虑这个串的贡献.我们把这个串扔到AC自动机里面跑.最后对经过每一个点到的这个点在fail树的根的路径上的点有1的贡献.求链的并,我们把这些点按DFS序排序,然后把每 ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...
- 【BZOJ-1103】大都市meg 树状数组 + DFS序
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2009 Solved: 1056[Submit][Sta ...
- POJ 3321 Apple Tree (树状数组+dfs序)
题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...
随机推荐
- Module.exports 和 exports
Module.exports 和 exports 在node中,没有全局作用域,只有模块作用域,外部访问不到内部,内部也访问不到外部,那么模块间如何通信 当加载一个模块的时候,被加载模块的代码在第一次 ...
- alg--动态规划(dynamic planning)
怎么开头呢? 一句话概括吧, dp的思想就是递归的反思想. 参考的理化: https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741374.h ...
- Mysql错误:#1054 - Unknown column '字段名' in 'field list'
# 1054 - Unknown column '字段名' in 'field list' 第一个就是你的表中没有这个字段 另一个就是你的这个字段前后可能有空格!!!,去掉空格即可!
- Grace Hopper 葛丽丝 霍普
Grace Murray Hopper(1906-1992), COBOL之母, Debug之母, A ship in port is safe, but that is not what ships ...
- [HTML5] a tag, rel="noopener"
It is a good pratice to add ref="noopener" <a href="/some/domain" target=&quo ...
- hdu 5410 CRB and His Birthday 01背包和全然背包
#include<stdio.h> #include<string.h> #include<vector> #include<queue> #inclu ...
- 英语发音规则---W字母
英语发音规则---W字母 一.总结 一句话总结: 1.W在单词开头发[w]? week [wiːk] n. 周,星期 win [wɪn] vt. 赢得 wake [weɪk] vi. 醒来 sweet ...
- 院校-德国:亚琛工业大学(RWTH)
ylbtech-院校-德国:亚琛工业大学(RWTH) 1.返回顶部 1. 亚琛工业大学(RWTH)成立于1870年,是德国著名理工类大学之一,也是世界顶尖理工类大学之一 ,长久以来被誉为“欧洲的麻省理 ...
- 34.QT模型(表格绘制)
modellex.h #ifndef MODELEX_H #define MODELEX_H #include <QAbstractItemModel> #include <QVec ...
- python一行代码实现9x9乘法表
for i in range(1,10): for j in range(1,i+1): print('%s * %s = %s ' %(i,j,i*j),end="") prin ...