SAM+线段树合并的裸题。

但我们讨论AC自动机的做法。

先建出AC自动机。考虑询问在[a,b]中出现的次数就是\([1,b]\)的出现次数-\([1,a-1]\)的出现次数。把询问离线。然后我们要求的就是第i个字符串在\([1,x]\)中出现次数。我们在从\([1,x-1]\)到\([1,x]\)的过程中把\(S_x\)放到AC自动机上跑,跑到的每一个节点都加1。然后询问就是在\(S_i\)在fail树上对应位置求一个子树和这个用树状数组维护就行。因为fail树上每一个节点的后代都包含这个节点。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int N=301000;
int n,m,ans[501000];
string s[N];
int cnt,head[N];
struct edge{
int to,nxt;
}e[N];
void add(int u,int v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
struct ques{
int x,k,id;
ques(int xx=0,int kk=0,int idx=0){
x=xx;k=kk;id=idx;
}
};
vector<ques> vec[N];
struct Tree{
int dep[N],size[N],dfn[N],tot;
int tr[N];
void dfs(int u,int f){
dep[u]=dep[f]+1;
dfn[u]=++tot;
size[u]=1;
int maxson=-1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
dfs(v,u);
size[u]+=size[v];
}
}
int lowbit(int x){
return x&-x;
}
void add(int x){
for(int i=x;i<=tot;i+=lowbit(i))tr[i]++;
}
int getsum(int x){
int tmp=0;
for(int i=x;i;i-=lowbit(i))tmp+=tr[i];
return tmp;
}
}tree;
bool cmp(int x,int y){
if(tree.dfn[x]<tree.dfn[y])return true;
else return false;
}
struct AC{
int trans[N][27],point[N],tot,fail[N];
void ins(string s,int k){
int now=0;
int len=s.size();
for(int i=0;i<len;++i){
if(trans[now][s[i]-'a'+1]==0)trans[now][s[i]-'a'+1]=++tot;
now=trans[now][s[i]-'a'+1];
}
point[k]=now;
}
void get_fail(){
queue<int> q;
for(int i=1;i<=26;++i)if(trans[0][i])q.push(trans[0][i]);
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=1;i<=26;++i)
if(trans[now][i])fail[trans[now][i]]=trans[fail[now]][i],q.push(trans[now][i]);
else trans[now][i]=trans[fail[now]][i];
}
}
void work(string s){
int now=0;
int len=s.size();;
tree.add(tree.dfn[0]);
for(int i=0;i<len;++i){
now=trans[now][s[i]-'a'+1];
tree.add(tree.dfn[now]);
}
}
}ac;
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;++i)cin>>s[i],ac.ins(s[i],i);
int a,b,c;
for(int i=1;i<=m;++i){
a=read();b=read();c=read();
vec[a-1].push_back(ques(ac.point[c],-1,i));
vec[b].push_back(ques(ac.point[c],1,i));
}
ac.get_fail();
for(int i=1;i<=ac.tot;++i)add(ac.fail[i],i);
tree.dfs(0,0);
for(int i=1;i<=n;++i){
ac.work(s[i]);
for(int j=0;j<vec[i].size();++j){
int L=tree.dfn[vec[i][j].x];
int R=tree.dfn[vec[i][j].x]+tree.size[vec[i][j].x]-1;
ans[vec[i][j].id]+=vec[i][j].k*(tree.getsum(R)-tree.getsum(L-1));
}
}
for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
return 0;
}

51nod 麦克打电话(AC自动机+树状数组)的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  3. BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Descript ...

  4. BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  5. HDU 6096 String(AC自动机+树状数组)

    题意 给定 \(n\) 个单词,\(q\) 个询问,每个询问包含两个串 \(s_1,s_2\),询问有多少个单词以 \(s_1\) 为前缀, \(s_2\) 为后缀,前后缀不能重叠. \(1 \leq ...

  6. bzoj 2434 AC自动机+树状数组

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3493  Solved: 1909[Submit][Sta ...

  7. [NOI2011]阿狸的打字机 --- AC自动机 + 树状数组

    [NOI2011] 阿狸的打字机 题目描述: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现, ...

  8. 【dfs序+AC自动机+树状数组】BZOJ2434-[Noi2011]阿狸的打字机

    [题目大意] 输入一个字符串,其中:(1)a..z:在字符串末尾添加当前字符(2)P:输出当前字符串(3)B:从当前字符串末尾删去一个字符. 给出m组查询,输出第i个输出的字符串在第j个输出的字符串内 ...

  9. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

随机推荐

  1. Codeforces Round #493 (Div. 2) C. Convert to Ones 乱搞_构造_好题

    题意: 给你一个长度为 nnn 的 010101串 ,你有两种操作: 1.将一个子串翻转,花费 XXX 2.将一个子串中的0变成1,1变成0,花费 YYY 求你将这个01串变成全是1的串的最少花费. ...

  2. Vue学习之路第五篇:v-bind

    v-bind:是Vue提供的用于绑定html属性的指令. html中常见的属性有:id.class.src.title.style等,他们都是以 名称/值对 的形式出现,如:id="firs ...

  3. 为什么要清除BSS段

    如题,看到uboot里有清除BSS段的代码,想知道这样做的目的是什么啊,BSS段默认值本来就是0了啊,希望大哥大姐们能详细的解说下,谢谢了 bss 段描述了未初始化的全局变量和静态变量的大小等信息,但 ...

  4. django-3-模板变量,过滤器,静态文件的引用

    <<<模板变量>>> (1)定义视图函数 通过context传递参数来渲染模板,context要是个字典 当模板变量为可调用对象的时候,函数不传递参数 (2)配置模 ...

  5. js中的json操作

    js中的json操作 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScr ...

  6. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 1.什么是Set?(what) Set是Collection容器的一个子接口,它不允许出现 ...

  7. Java分布式爬虫Nutch教程——导入Nutch工程,执行完整爬取

    Java分布式爬虫Nutch教程--导入Nutch工程,执行完整爬取 by briefcopy · Published 2016年4月25日 · Updated 2016年12月11日 在使用本教程之 ...

  8. ASP.NET-MVC中Entity和Model之间的关系

    Entity 与 Model之间的关系图 ViewModel类是MVC中与浏览器交互的,Entity是后台与数据库交互的,这两者可以在MVC中的model类中转换 MVC基础框架 来自为知笔记(Wiz ...

  9. Apache Mahout 0.9、10.1、11. CardinalityException: Required cardinality 60 but got 29

      我们可以使用Apache Mahout来快速创建高效扩展性又好的机器学习应用.Mahout结合了诸如H2O算法.Scala.Spark和Hadoop MapReduce等模块,为开发人员提供了一个 ...

  10. 在 RedHat/CentOS 7.x 中使用 nmcli 命令管理网络

    在 RedHat/CentOS 7.x 中使用 nmcli 命令管理网络 学习了:https://linux.cn/article-5410-1.html#3_3613 http://www.linu ...