【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡
http://www.lydsy.com/JudgeOnline/problem.php?id=3926
广义后缀自动机的例题,感觉广义后缀自动机好恶心。。。
广义后缀自动机是对一个trie建立的后缀自动机,能识别trie上的所有子串。right集合代表的是trie树上的节点集合。
具体做法是把last移到“在trie树上要添加节点的节点”在后缀自动机的状态节点上,然后套插入模板。
插入模板的运行过程跟对一个串建立后缀自动机有些不同。
假设插入w,首先np节点的\(|Right|\)可以不再等于1,而且如果last存在w的转移函数,特判一下转移到的点的maxlen是否为last的maxlen+1。如果是,直接把last移到这个点就行了。
不移动也可以,这样会新建一个np节点,np->par为last->go,相当于把np和last->go看成一个点。
如果转移到的点的maxlen大于last的maxlen,那么在插入模板里需要新建一个nq节点,nq的maxlen为last的maxlen+1。
同时插入模板里还要把np和q的par指针指向nq。注意这里np和nq的right集合是完全相同的!但是np->par=nq,不符合后缀自动机里“真包含”的定义,不过我们还是可以把这里的np和nq看成一个点。
其他情况跟一般的后缀自动机构造一样。
最后把last移向np,如果np和nq的right集合完全相同,就把它们一起看成一个“大点”,last在np上没有某个转移函数就跳到nq上看有没有这个转移函数,相当于这个“大点”的转移函数是np和nq的转移函数的并集。
时空复杂度还是\(O(n)\)。
在mrazer神犇的帮助下终于理解了qwq
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ans = 0;
struct State {
State *par, *go[10];
int val;
State(int _num) : val(_num) {par = 0; memset(go, 0, sizeof(go));}
} *root, *last;
void extend(int w) {
if (last->go[w] && last->go[w]->val == last->val + 1) {
last = last->go[w];
return;
}
State *p = last;
State *np = new State(p->val + 1);
while (p && p->go[w] == 0)
p->go[w] = np, p = p->par;
if (p == 0) np->par = root;
else {
State *q = p->go[w];
if (p->val + 1 == q->val) np->par = q;
else {
State *nq = new State(p->val + 1);
memcpy(nq->go, q->go, sizeof(q->go));
nq->par = q->par;
q->par = np->par = nq;
while (p && p->go[w] == q)
p->go[w] = nq, p = p->par;
}
}
last = np; ans += np->val - np->par->val;
}
const int N = 100003;
int n, c, cnt = 0, point[N], du[N], col[N];
struct node {int nxt, to;} E[N << 1];
void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;}
void dfs(int x, int fa) {
extend(col[x]);
State *now = last;
for (int i = point[x], v = E[i].to; i; v = E[i = E[i].nxt].to)
if (v != fa) {
dfs(v, x);
last = now;
}
}
int main() {
root = last = new State(0);
scanf("%d%d", &n, &c);
for (int i = 1; i <= n; ++i) scanf("%d", col + i);
int u, v;
for (int i = 1; i < n; ++i) {
scanf("%d%d", &u, &v);
ins(u, v); ins(v, u);
++du[u]; ++du[v];
}
for (int i = 1; i <= n; ++i)
if (du[i] == 1)
last = root, dfs(i, -1);
printf("%lld\n", ans);
return 0;
}
下面的是讨论版的没有任何多余的节点的广义后缀自动机(及不需要把两个点理解成一个大点),感觉自己好闲啊qwq
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll ans = 0;
struct State {
State *par, *go[10];
int val;
State(int _num) : val(_num) {par = 0; memset(go, 0, sizeof(go));}
} *root, *last;
void extend(int w) {
if (last->go[w] && last->go[w]->val == last->val + 1) {
last = last->go[w];
return;
}
State *p = last;
State *np = new State(p->val + 1);
while (p && p->go[w] == 0)
p->go[w] = np, p = p->par;
if (p == 0) np->par = root;
else {
State *q = p->go[w];
if (p->val + 1 == q->val) np->par = q;
else if (p != last) {
State *nq = new State(p->val + 1);
memcpy(nq->go, q->go, sizeof(q->go));
nq->par = q->par;
q->par = np->par = nq;
while (p && p->go[w] == q)
p->go[w] = nq, p = p->par;
} else {
memcpy(np->go, q->go, sizeof(q->go));
np->par = q->par;
q->par = np;
while (p && p->go[w] == q)
p->go[w] = np, p = p->par;
last = np; return;
}
}
last = np; ans += last->val - last->par->val;
}
const int N = 100003;
int n, c, cnt = 0, point[N], du[N], col[N];
struct node {int nxt, to;} E[N << 1];
void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;}
void dfs(int x, int fa) {
extend(col[x]);
State *now = last;
for (int i = point[x], v = E[i].to; i; v = E[i = E[i].nxt].to)
if (v != fa) {
dfs(v, x);
last = now;
}
}
int main() {
root = last = new State(0);
scanf("%d%d", &n, &c);
for (int i = 1; i <= n; ++i) scanf("%d", col + i);
int u, v;
for (int i = 1; i < n; ++i) {
scanf("%d%d", &u, &v);
ins(u, v); ins(v, u);
++du[u]; ++du[v];
}
for (int i = 1; i <= n; ++i)
if (du[i] == 1)
last = root, dfs(i, -1);
printf("%lld\n", ans);
return 0;
}
【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡的更多相关文章
- BZOJ 3926 && ZJOI 2015 诸神眷顾的幻想乡 (广义后缀自动机)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MB Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽 ...
- 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 974 Solved: 573 Descriptio ...
- ZJOI 2015 诸神眷顾的幻想乡
题目描述 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常 ...
- BZOJ 3926 诸神眷顾的幻想乡
BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1017 Solved: 599[Submit][S ...
- 字符串(广义后缀自动机):BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 843 Solved: 510[Submit][St ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]
3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1124 Solved: 660[Submit][S ...
- BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡
3926: [Zjoi20150]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 438 Solved: 273 Descripti ...
- BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机)
BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机) 题面 自己找去 HINT 我们可以把题目拆解成几个部分,首先我们手玩一个结论,从所有的叶子节点出发,遍历整 ...
- 【BZOJ3926】诸神眷顾的幻想乡(后缀自动机)
[BZOJ3926]诸神眷顾的幻想乡(后缀自动机) 题面 BZOJ 题解 广义后缀自动机啦 求多个串的不同子串个数? 当然是后缀自动机,最后只要把\(longest-parent.longest\)求 ...
随机推荐
- android app开发
android 中文文档: http://www.android-doc.com/training/index.html 二维码在线自动生成.http://www.liantu.com/
- [Java]读取文件方法大全(转)
[Java]读取文件方法大全 1.按字节读取文件内容2.按字符读取文件内容3.按行读取文件内容 4.随机读取文件内容 public class ReadFromFile { /** ...
- Ubuntu + VMware=Linux虚拟机
1.工具 2.要点 3.问题 有时间再写
- 需要注意的subList方法!和substring是不一样的!从源码解释他们的不同。
很多时候我们截取字符串用的是substring方法,很自然用着,但是对于列表的截取时很多时候就用得很少,但是其实他们是很不一样的,具体哪里不一样呢? package main; import java ...
- js学习之函数
1/.js中函数就是对象. 2/以表达式方式定义的函数一般不要函数名以使代码紧凑. 3/js中函数声明的方式会被默认提到外部脚本或最前面,所以在其定义前的代码也可调用. 然而以表达式方式的则不行. 4 ...
- hibernate---关联关系的 crud_cascade_fetch
CRUD怎么写?? 存user信息, 自动存group信息 user.java package com.bjsxt.hibernate; import javax.persistence.Cascad ...
- 第一次在手机上跑动ane
记录一下: 打包的时候先出现 error 100: descriptor cannot be parsed, 原因是命名空间少了个引号,自己粗心所致 第二次打包出现了invalid namespace ...
- WebRequest调用
WebRequest支持不同的浏览器对象,可以在底层使用不同的XMLHttpRquest方式调用Web服务. Time.aspx <%@ Page Language="C#" ...
- (中等) POJ 2886 Who Gets the Most Candies? , 反素数+线段树。
Description N children are sitting in a circle to play a game. The children are numbered from 1 to N ...
- OPENCV图像特征点检测与FAST检测算法
前面描述角点检测的时候说到,角点其实也是一种图像特征点,对于一张图像来说,特征点分为三种形式包括边缘,焦点和斑点,在OPENCV中,加上角点检测,总共提供了以下的图像特征点检测方法 FAST SURF ...