建出AC自动机及其fail树,每次给新加入的串在AC自动机上经过的点染色,问题即转化为子树颜色数。显然可以用dfs序转成序列问题树状数组套权值线段树解决,显然过不掉。事实上直接树上差分,按dfs序排序后lca处-1,树状数组维护子树和即可。

  又一次写了cmp后没放进sort,心态爆炸。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 2000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,trie[N][],fail[N],val[N],id[N],q[N],tree[N],end[N],tmp[N],cnt;
char s[N];
void add(int k,int x){while (k<=cnt) tree[k]+=x,k+=k&-k;}
int query(int k){int s=;while (k) s+=tree[k],k-=k&-k;return s;}
namespace Tree
{
int p[N],t,dfn[N],size[N],fa[N][],deep[N],cnt;
struct data{int to,nxt;}edge[N];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
dfn[k]=++cnt;size[k]=;
for (int i=p[k];i;i=edge[i].nxt)
{
deep[edge[i].to]=deep[k]+;
fa[edge[i].to][]=k;
dfs(edge[i].to);
size[k]+=size[edge[i].to];
}
}
void build()
{
cnt=;dfs();
for (int j=;j<;j++)
for (int i=;i<cnt;i++)
fa[i][j]=fa[fa[i][j-]][j-];
}
int lca(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
for (int j=;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];
if (x==y) return x;
for (int j=;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
return fa[x][];
}
}
void ins(char *s,int n,int p)
{
int k=;
for (int i=;i<=n;i++)
{
if (!trie[k][s[i]-'a']) trie[k][s[i]-'a']=++cnt;
k=trie[k][s[i]-'a'];
}
end[p]=k;
}
void build()
{
int head=,tail=;for (int i=;i<;i++) if (trie[][i]) q[++tail]=trie[][i],Tree::addedge(,trie[][i]);
do
{
int x=q[++head];
for (int i=;i<;i++)
if (trie[x][i]) fail[trie[x][i]]=trie[fail[x]][i],Tree::addedge(fail[trie[x][i]],trie[x][i]),q[++tail]=trie[x][i];
else trie[x][i]=trie[fail[x]][i];
}while (head<tail);
Tree::build();
}
bool cmp(const int&a,const int&b)
{
return Tree::dfn[a]<Tree::dfn[b];
}
void run(char *a,int n)
{
int k=,cnt=;tmp[++cnt]=;
for (int i=;i<=n;i++) tmp[++cnt]=k=trie[k][a[i]-'a'];
sort(tmp+,tmp+cnt+,cmp);
for (int i=;i<=cnt;i++) add(Tree::dfn[tmp[i]],);
for (int i=;i<=cnt;i++) add(Tree::dfn[Tree::lca(tmp[i-],tmp[i])],-);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3881.in","r",stdin);
freopen("bzoj3881.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
m=read();
for (int i=;i<=m;i++)
{
scanf("%s",s+);n=strlen(s+);
ins(s,n,i);
}
build();cnt++;
m=read();
while (m--)
{
int op=read();
if (op==)
{
scanf("%s",s+);n=strlen(s+);
run(s,n);
}
else
{
int x=read();
printf("%d\n",query(Tree::dfn[end[x]]+Tree::size[end[x]]-)-query(Tree::dfn[end[x]]-));
}
}
return ;
}

BZOJ3881 Coci2015Divljak(AC自动机+树上差分+树状数组)的更多相关文章

  1. BZOJ_2434_[NOI2011]_阿狸的打字机_(AC自动机+dfs序+树状数组)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2434 给出\(n\)个字符串,\(m\)个询问,对于第\(i\)个询问,求第\(x_i\)个字 ...

  2. BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组

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

  3. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

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

  4. 【AC自动机】【树状数组】【dfs序】洛谷 P2414 [NOI2011]阿狸的打字机 题解

        这一题是对AC自动机的充分理解和树dfs序的巧妙运用. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和' ...

  5. NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)

    题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...

  6. P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)

    解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  8. BZOJ2434: [NOI2011]阿狸的打字机(AC自动机+dfs序+树状数组)

    [NOI2011]阿狸的打字机 题目链接:https://www.luogu.org/problemnew/show/P2414 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. ...

  9. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

随机推荐

  1. js获取图片的原始尺寸

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  2. 第18章 SysTick—系统定时器

    第18章     SysTick—系统定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  3. VMware 克隆多台Linux机器并配置IP

    1.查看并分配虚拟网络 我们首先要知道 VMware 三种网络模式的区别. ①.Bridged(桥接模式):就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信.在桥接的作用下,类似于把物理主机虚拟为 ...

  4. test temp

    http://img3.cache.netease.com/love/cssjs/20026/script/page/common.jshttp://img3.cache.netease.com/lo ...

  5. Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题

    原文:Nuget包CommonServiceLocator从1.0.3升级到2.0.4时MvvmLight的ViewModelLocator初始化SimpleIoc.Default格式不匹配问题 把旧 ...

  6. python绘制三维图

    作者:桂. 时间:2017-04-27  23:24:55 链接:http://www.cnblogs.com/xingshansi/p/6777945.html 本文仅仅梳理最基本的绘图方法. 一. ...

  7. Eclipse编辑器设置

    1. 自己不太喜欢Eclipse按回车后自动插入参数的默认选项. 可以在Window-Preferences-Java-Editor-Content Assist选项里,将Fill method ar ...

  8. 【Orleans开胃菜系列2】连接Connect源码简易分析

    [Orleans开胃菜系列2]连接Connect源码简易分析 /** * prism.js Github theme based on GitHub's theme. * @author Sam Cl ...

  9. 使用Memcached提高.NET应用程序的性能(转)

    标签:分布式缓存 .NET Memcached Performance 性能 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zh ...

  10. OpenCV操作像素

    在了解了图像的基础知识和OpenCV的基础知识和操作以后,接下来我们要做的就对像素进行操作,我们知道了图像的本质就是一个矩阵,那么一个矩阵中存储了那么多的像素,我们如何来操作呢?下面通过几个例子来看看 ...