【BZOJ 3881】【COCI 2015】Divljak
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的更多相关文章
- 【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)
4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 370 Solved: 237 De ...
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 【MyEclipse 2015】 逆向破解实录系列【终】(纯研究)
声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...
- 【MyEclipse 2015】 逆向破解实录系列【2】(纯研究)
声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...
- 【BZOJ】3319: 黑白树
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...
- 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...
- 【CEDEC 2015】【夏日课堂】制作事宜技术篇,新手职员挑战VR Demo开发的真相
日文原文地址 http://www.4gamer.net/games/277/G027751/20150829002/ PS:CEDEC 2015的PPT有些要到10月才有下载,目前的都是记者照片修图 ...
- 【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。
[SIGGRAPH 2015][巫师3 狂猎 The Witcher 3: Wild Hunt ]顶级的开放世界游戏的实现技术 作者:西川善司 日文链接 http://www.4gamer.net/ ...
- 【BZOJ】【2084】【POI2010】Antisymmetry
Manacher算法 啊……Manacher修改一下就好啦~蛮水的…… Manacher原本是找首尾相同的子串,即回文串,我们这里是要找对应位置不同的“反回文串”(反对称?233) 长度为奇数的肯定不 ...
随机推荐
- 【BZOJ】1031 [JSOI2007]字符加密Cipher
[算法]后缀数组 [题解]把数组复制一遍然后SA处理即可. 后缀数组 #include<cstdio> #include<algorithm> #include<cstr ...
- Spring 与 Quartz 动态配置(数漫江湖)
因为项目的需求,需要有动态配置计划任务的功能.本文在 Quartz JobBean 中获取配置的 Quartz cronExpression 时间表达式及 Spring Bean 的对象名.方法名并运 ...
- Can you answer these queries?(HDU4027+势能线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题目: 题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和. 思路:易 ...
- V4L2(二)虚拟摄像头驱动vivi深入分析【转】
转自:http://www.cnblogs.com/tureno/articles/6694463.html 转载于: http://blog.csdn.net/lizuobin2/article/d ...
- 64_g5
golang-github-kr-text-devel-0-0.11.git6807e77.f..> 11-Feb-2017 07:48 14250 golang-github-kr-text- ...
- 下载 LFS所需要的源码包的脚本程序及检验方法
下载 LFS所需要的源码包的脚本程序及检验方法 http://blog.csdn.net/yygydjkthh/article/details/45315143
- JQUERY 提取多个元素 a img 的 src href
<div class="abc"><a href="1.html"><img src="1.jpg"/> ...
- www.verycd.com
#encoding=utf-8 import urllib import urllib2 postdate = urllib.urlencode({'continueURL':'http://www. ...
- transition结合:after,:before实现动画
div代码 <div class='div'> hover </div> css代码 .div{ width:200px; height:100px; line-height: ...
- php文件上传需要的配置
服务端配置(php.ini) 1.file_uploads=On //支持HTTP上传 2.upload_tmp_dir =”” //临时文件保存的目录 3.upload_max_filesize ...