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节点以及它子树的值之和.初 ...
随机推荐
- obj-c部分对象快捷赋值和取值
NSNumber: NSNumber *number = @1234; 旧的方式: NSArray *physicsValues = [NSArrayarrayWithObjects: [NSNumb ...
- json字符串通俗的介绍
json 的本质就是字符串,按key:value这种键值对的格式定义的字符串 json就是传递javascript对象的语法,json只有两种结构,对象和数组,这两种结构嵌套和组合,来表示各种各样的数 ...
- 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple
CRB and Apple Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- javascript操作window对象
document.defaultView或全局变量window--获取一个window对象. 1)获取窗体信息 innerHeight.innerWidth--获取窗体内容区域的高度.宽度. oute ...
- OpenLayers3基础教程——OL3 介绍control
概述: 本文讲述的是Ol3中的control的介绍和应用. OL2和OL3 control比較: 相比較Ol2的control,OL3显得特别少,下图分别为Ol2和Ol3的control: Ol2的c ...
- 【LeetCode-面试算法经典-Java实现】【056-Merge Intervals(区间合并)】
[056-Merge Intervals(区间合并)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a collection of intervals, ...
- Android測试APP工具(一)
近期面试APP开发者的时候,遇到了技术总监问 APP測试的概念性问题.后面感觉主要的项目流程.项目逻辑.屏幕适配. 測试是全然没有问题的.可是对于APP的性能測试.压力測试等高端的測试.还是存在着美中 ...
- php PDO连接mysql
近期在linux装了新的环境.php5.6+mysql5.5+nginx. 然后用原来的mysql链接数据库出现的错误. 原因就是说连接数据库的方法太旧.建议我用mysqli和PDO来连接数据库. 好 ...
- DAC0832、led、蜂鸣器
52控制DAC0832芯片输出电流,让发光二极管D12由灭均匀变到最亮.再有亮变灭.在最亮和最灭的时候蜂鸣器发出报警声,完毕整个周期的时间是控制在5s左右. #include<reg52.h&g ...
- SqlHelper——仅仅由于在人群中多看了你一眼
一.SqlHelper 出场 不是由于大家都在用SqlHelper所以才用,是由于连接数据库关闭数据库查询数据库的多了也就加上了SqlHelper.当你的非常多需求都有一个同样的方法的时候我们没有必要 ...