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】诸神眷顾的幻想乡的更多相关文章

  1. BZOJ 3926 && ZJOI 2015 诸神眷顾的幻想乡 (广义后缀自动机)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MB Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽 ...

  2. 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 974  Solved: 573 Descriptio ...

  3. ZJOI 2015 诸神眷顾的幻想乡

    题目描述 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常 ...

  4. BZOJ 3926 诸神眷顾的幻想乡

    BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...

  5. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1017  Solved: 599[Submit][S ...

  6. 字符串(广义后缀自动机):BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 843  Solved: 510[Submit][St ...

  7. BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 [广义后缀自动机 Trie]

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1124  Solved: 660[Submit][S ...

  8. BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡

    3926: [Zjoi20150]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 438  Solved: 273 Descripti ...

  9. BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机)

    BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机) 题面 自己找去 HINT 我们可以把题目拆解成几个部分,首先我们手玩一个结论,从所有的叶子节点出发,遍历整 ...

  10. 【BZOJ3926】诸神眷顾的幻想乡(后缀自动机)

    [BZOJ3926]诸神眷顾的幻想乡(后缀自动机) 题面 BZOJ 题解 广义后缀自动机啦 求多个串的不同子串个数? 当然是后缀自动机,最后只要把\(longest-parent.longest\)求 ...

随机推荐

  1. spider JAVA如何判断网页编码 (转载)

    原文链接 http://www.cnblogs.com/nanxin/archive/2013/03/27/2984320.html 前言 最近做一个搜索项目,需要爬取很多网站获取需要的信息.在爬取网 ...

  2. USACO Section 1.1 Broken Necklace 解题报告

    题目 题目描述 有一串项链,它是由红蓝白三种颜色的珠子组成的,b代表蓝色,w代表白色,r代表红色,当它完整的时候是一个闭合的环形.现在它在某一个节点断裂了,之前的环形也随之变成了直线形.从两端开始收集 ...

  3. PHP文件夹操作

    文件:文件+目录 判断文件类型: filetype("路径"); //返回一个字符串 is_dir("路径"); //如果是目录会返回true 判断文件是不是目 ...

  4. 数据同步方案(附Java源码)

    一.问题背景经常碰到要同步数据的情况,而系统自带的复制功能又不能实现增量同步,每次都要做全量复制,发生异常情况后只能重头再来,非常麻烦,优其是对那种大文件的处理,更是耗时.二.解決方案1.计算源目录数 ...

  5. JQuery常用动画实现函数

    1.上拉.下拉和切换 slideup().slidedown().slideToggle() JQuery里面的切换太吊了,它自带判断当前显示状态,如果为显示就执行隐藏,如果为隐藏就执行显示. 2.淡 ...

  6. 制作win10 usb 启动盘

    Rufus 是一个开源的USB启动盘制作程序.其特点就是快速,且支持各种系统,包括各种windows系统,linux系统,使用也很简单. Rufus主页: http://rufus.akeo.ie/ ...

  7. (四)Jquery Mobile表单

    Jquery Mobile表单与列表 一.JM表单      1.表单      普通html表单            效果:          2.只能输入数字的表单           效果:  ...

  8. NBUT 1457 Sona

    莫队算法+离散化 1.map会TLE,必须离散化做 2.long long会WA,__int64定义 %I64d输出输出能AC 3.注意输入的序列会爆int #include<cstdio> ...

  9. (简单) POJ 3264 Balanced Lineup,RMQ。

    Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...

  10. c3p0、dbcp、tomcat jdbc pool 连接池配置简介及常用数据库的driverClass和驱动包

    [-] DBCP连接池配置 dbcp jar包 c3p0连接池配置 c3p0 jar包 jdbc-pool连接池配置 jdbc-pool jar包 常用数据库的driverClass和jdbcUrl ...