http://www.lydsy.com/JudgeOnline/problem.php?id=3881

好难的一道题啊qwq

一开始我想对T建AC自动机,根本不可做。

正解是对S建AC自动机。

fail树的性质:一棵子树中所有的点都有子树的根这个后缀。

对于要插入的一个串\(P_x\),我们在AC自动机上匹配它。

考虑问题要问\(S_x\)是多少\(P_x\)的子串,子串可以表示成一个前缀的后缀。

匹配过程中经过的所有点都可以当做\(P_x\)的一个前缀,暴力做法是对每个当做\(P_x\)前缀的点暴力沿着fail指针往上跳,对经过的所有点染上一种颜色。

回答询问就是回答代表\(S_x\)的结点有多少不同的颜色。

对于上面那个暴力做法,可以在每个代表\(P_x\)前缀的结点上打上颜色,回答询问直接统计子树里有多少种不同的颜色即可。

可以用bits维护dfs序,但在一棵子树里同一种颜色可能有两个,对这棵子树的dfs序贡献必须是1。

有一个非常神奇的东西,把当前所有要打上颜色的结点按dfs序排序,每个节点上+1,排序后相邻结点的lca出-1。

这样对于一棵子树里的所有颜色相同的结点,它们总的贡献是1。

好神啊,不过\(2*10^6\)能用\(O(n\log n)\)?

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N = 2000003; struct node {int nxt, to;} E[N];
int id[N], qu[N], ch[N][26], cnt = 0, cnt2 = 1, fail[N], point[N];
void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;} void insert(int num, char *s) {
int x, tmp = 1, len = strlen(s);
for (int i = 0; i < len; ++i) {
x = s[i] - 'a';
if (ch[tmp][x] != 0) tmp = ch[tmp][x];
else tmp = ch[tmp][x] = ++cnt2;
}
id[num] = tmp;
} void BFS() {
int p = 0, q = 1, f, x, v; qu[1] = 1;
while (p != q) {
x = qu[++p];
for (int i = 0; i < 26; ++i)
if (ch[x][i]) {
v = qu[++q] = ch[x][i];
f = fail[x];
while (f && ch[f][i] == 0)
f = fail[f];
fail[v] = f ? ch[f][i] : 1;
ins(fail[v], v);
}
}
} int tot = 0, n, deep[N], L[N], R[N], sz[N], top[N], son[N], fa[N];
char s[N]; void dfs(int x) {
L[x] = ++tot; sz[x] = 1;
for (int i = point[x], v = E[i].to; i; v = E[i = E[i].nxt].to) {
fa[v] = x; deep[v] = deep[x] + 1;
dfs(v); sz[x] += sz[v];
if (son[x] == 0 || sz[v] > sz[son[x]])
son[x] = v;
}
R[x] = tot;
} void dfs2(int x) {
if (son[x]) {
top[son[x]] = top[x];
dfs2(son[x]);
}
for (int i = point[x], v = E[i].to; i; v = E[i = E[i].nxt].to)
if (v != son[x])
top[v] = v, dfs2(v);
} int LCA(int x, int y) {
while (top[x] != top[y]) {
if (deep[top[x]] < deep[top[y]])
swap(x, y);
x = fa[top[x]];
}
return deep[x] < deep[y] ? x : y;
} bool cmp(int x, int y) {return L[x] < L[y];}
int bits[N], a[N]; void update(int x, int d) {
for (; x <= tot; x += (x & (-x)))
bits[x] += d;
}
int sum(int x) {
int ret = 0;
for (; x; x -= (x & (-x)))
ret += bits[x];
return ret;
} void add(char *s) {
int len = strlen(s), x, tmp = 1, tt = 0;
for (int i = 0; i < len; ++i) {
x = s[i] - 'a';
if (ch[tmp][x]) tmp = ch[tmp][x];
else {
while (tmp && ch[tmp][x] == 0) tmp = fail[tmp];
if (ch[tmp][x]) tmp = ch[tmp][x];
else tmp = 1;
}
a[++tt] = tmp;
update(L[tmp], 1);
}
stable_sort(a + 1, a + tt + 1, cmp);
for (int i = 2; i <= tt; ++i)
update(L[LCA(a[i - 1], a[i])], -1);
} int Sum(int x) {
return sum(R[x]) - sum(L[x] - 1);
} int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%s", s);
insert(i, s);
}
BFS();
dfs(1);
top[1] = 1; dfs2(1); int q, op;
scanf("%d", &q);
while (q--) {
scanf("%d", &op);
if (op == 1) {
scanf("%s", s);
add(s);
} else {
scanf("%d", &op);
printf("%d\n", Sum(id[op]));
}
}
return 0;
}

【BZOJ 3881】【COCI 2015】Divljak的更多相关文章

  1. 【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 370  Solved: 237 De ...

  2. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  3. 【MyEclipse 2015】 逆向破解实录系列【终】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

  4. 【MyEclipse 2015】 逆向破解实录系列【2】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

  5. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  6. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  7. 【CEDEC 2015】【夏日课堂】制作事宜技术篇,新手职员挑战VR Demo开发的真相

    日文原文地址 http://www.4gamer.net/games/277/G027751/20150829002/ PS:CEDEC 2015的PPT有些要到10月才有下载,目前的都是记者照片修图 ...

  8. 【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。

    [SIGGRAPH 2015][巫师3 狂猎 The Witcher 3: Wild Hunt ]顶级的开放世界游戏的实现技术 作者:西川善司 日文链接  http://www.4gamer.net/ ...

  9. 【BZOJ】【2084】【POI2010】Antisymmetry

    Manacher算法 啊……Manacher修改一下就好啦~蛮水的…… Manacher原本是找首尾相同的子串,即回文串,我们这里是要找对应位置不同的“反回文串”(反对称?233) 长度为奇数的肯定不 ...

随机推荐

  1. 【BZOJ】1031 [JSOI2007]字符加密Cipher

    [算法]后缀数组 [题解]把数组复制一遍然后SA处理即可. 后缀数组 #include<cstdio> #include<algorithm> #include<cstr ...

  2. Spring 与 Quartz 动态配置(数漫江湖)

    因为项目的需求,需要有动态配置计划任务的功能.本文在 Quartz JobBean 中获取配置的 Quartz cronExpression 时间表达式及 Spring Bean 的对象名.方法名并运 ...

  3. Can you answer these queries?(HDU4027+势能线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题目: 题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和. 思路:易 ...

  4. V4L2(二)虚拟摄像头驱动vivi深入分析【转】

    转自:http://www.cnblogs.com/tureno/articles/6694463.html 转载于: http://blog.csdn.net/lizuobin2/article/d ...

  5. 64_g5

    golang-github-kr-text-devel-0-0.11.git6807e77.f..> 11-Feb-2017 07:48 14250 golang-github-kr-text- ...

  6. 下载 LFS所需要的源码包的脚本程序及检验方法

    下载 LFS所需要的源码包的脚本程序及检验方法 http://blog.csdn.net/yygydjkthh/article/details/45315143

  7. JQUERY 提取多个元素 a img 的 src href

    <div class="abc"><a href="1.html"><img src="1.jpg"/> ...

  8. www.verycd.com

    #encoding=utf-8 import urllib import urllib2 postdate = urllib.urlencode({'continueURL':'http://www. ...

  9. transition结合:after,:before实现动画

    div代码 <div class='div'> hover </div> css代码 .div{ width:200px; height:100px; line-height: ...

  10. php文件上传需要的配置

    服务端配置(php.ini) 1.file_uploads=On  //支持HTTP上传 2.upload_tmp_dir =”” //临时文件保存的目录 3.upload_max_filesize ...