BZOJ3881 Coci2015Divljak(AC自动机+树上差分+树状数组)
建出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自动机+树上差分+树状数组)的更多相关文章
- BZOJ_2434_[NOI2011]_阿狸的打字机_(AC自动机+dfs序+树状数组)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2434 给出\(n\)个字符串,\(m\)个询问,对于第\(i\)个询问,求第\(x_i\)个字 ...
- BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组
题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...
- 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组
[BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...
- 【AC自动机】【树状数组】【dfs序】洛谷 P2414 [NOI2011]阿狸的打字机 题解
这一题是对AC自动机的充分理解和树dfs序的巧妙运用. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和' ...
- NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)
题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...
- P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)
解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- BZOJ2434: [NOI2011]阿狸的打字机(AC自动机+dfs序+树状数组)
[NOI2011]阿狸的打字机 题目链接:https://www.luogu.org/problemnew/show/P2414 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
随机推荐
- STM32 低功耗 调试心得
MCU在进入STOP模式的时候,GPIO的状态都是保持在进入低功耗模式之前的状态,在最小系统中,MCU的GPIO都是悬空的,所以设置为何种状态都不会影响到功耗.但当连接到外设后,外设的电平状态和所连接 ...
- Java IO详解(七)------随机访问文件流
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocea ...
- Android Notification的使用 - z
http://blog.csdn.net/new_one_object/article/details/55511253 另,博主其它文章也很好
- 2017-2018-2 20155203《网络对抗技术》Exp5 MSF基础应用
1.实践过程记录 1.1一个主动攻击实践,如ms08_067; msf > search ms08_067_netapi //查看可以用的工具 [!] Module database cache ...
- 20155210 Exp5 MSF基础应用
Exp5 MSF基础应用 一个主动攻击实践,MS08-067 首先利用msfconsole启用msf终端 然后利用search MS08-067搜索漏洞,会显示相应漏洞模块 如图: 根据上图,我们输入 ...
- VS编程,WPF单独更改TextBlock中部分文字格式的一种方法
原文:VS编程,WPF单独更改TextBlock中部分文字格式的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/articl ...
- Pick定理、欧拉公式和圆的反演
Pick定理.欧拉公式和圆的反演 Tags:高级算法 Pick定理 内容 定点都是整点的多边形,内部整点数为\(innod\),边界整点数\(ednod\),\(S=innod+\frac{ednod ...
- suggest braces around empty body in an 'if' statement
出现这种错误是要求加大括号
- [CF1038F]Wrap Around[AC自动机+dp]
题意 题目链接 分析 题意容易转化成求循环之后不包含 \(s\) 的串的个数. 首先建立 AC 自动机.考虑一个暴力的做法:枚举长度为 \(n\) 的字符串 \(t\) 最终(后缀) 和 \(s\) ...
- python3 subprocess模块
当我们在执行python程序的时候想要执行系统shell可以使用subprocess,这时可以新起一个进程来执行系统的shell命令,python3常用的有subprocess.run()和subpr ...