建出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. -bash: start-all.sh: 未找到命令

    解决方案:以root权限进入,找到hadoop安装的目录,进入sbin目录下 输入命令#start-all.sh 出现错误:-bash: start-all.sh: 未找到命令 百度了一下:原来需要输 ...

  2. [SDOI2012]任务安排 BZOJ2726 斜率优化+二分查找

    网上的题解...状态就没有一个和我一样的...这让我有些无从下手... 分析: 我们考虑,正常的斜率优化满足x(i)单调递增,k(i)单调递增,那么我们就可以只用维护一个单调队列满足对于当前的x(i) ...

  3. WPF bind baidu Image

     as there baidu image has protect refer from other site to use. need download i use request header a ...

  4. 20155317王新玮《网络对抗》Exp2 后门原理与实践

    20155317王新玮<网络对抗>Exp2 后门原理与实践 一.实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划 ...

  5. python 字符串的split()函数详解

    split翻译为分裂.  split()就是将一个字符串分裂成多个字符串组成的列表. split()当不带参数时以空格进行分割,当代参数时,以该参数进行分割. //---当不带参数时 example: ...

  6. 汇编 REPE/REPZ 指令,CMPSB指令

    知识点: REPE/REPZ 指令 CMPSB 指令 一.CMPSB //cmp //sub //SCASB//scasw//scasd cmp byte ptr [edi],al //对标志位的 ...

  7. 解决 引入本地jar包后 maven无法编译的问题及部署war包缺失本地jar包的问题

    参考:https://blog.csdn.net/wang864676212/article/details/82626922 pom.xml 引入 <plugin> <plugin ...

  8. ES6 之reduce的高级技巧

    reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值.reduce() 方法接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 ...

  9. R绘图 第八篇:绘制饼图(ggplot2)

    geom_bar()函数不仅可以绘制条形图,还能绘制饼图,跟绘制条形图的区别是坐标系不同,绘制饼图使用的坐标系polar,并且设置theta="y": coord_polar(th ...

  10. 初级字典树查找在 Emoji、关键字检索上的运用 Part-2

    系列索引 Unicode 与 Emoji 字典树 TrieTree 与性能测试 生产实践 在有了 Unicode 和 Emoji 的知识准备后,本文进入编码环节. 我们知道 Emoji 是 Unico ...