【ZJOI2015】诸神眷顾的幻想乡(广义后缀自动机)
来源:互联网 发布:淘宝卖家怎么删除订单 编辑:程序博客网 时间:2024/05/16 05:44
题目大意:
有一棵有n个节点的树,每个节点上有一个数字。
求所有树的路径中,所形成的字符串中不同的有多少个。
1<=n<=10^5
叶子节点数小于20。
题解:
其实我很不解一个裸的不能再裸的题为什么会是ZJOI Day1 的最后一题(暴%Po姐)。
也许是因为后缀自动机2012年才提出来吧。
首先注意叶子节点数小于20。
这启发我们以它们为根,去建树,这样会有20个trie,再合并,就有一棵大tried。
现在的问题在于求这棵trie的不同子串数(注意子串是自上到下的路径)。
这就是广义后缀自动机的裸题。
那么广义后缀自动机和后缀自动机有什么区别呢?
其实在我的眼里,并没有。
后缀自动机是一个串一直做到底。
对于广义后缀自动机(trie的后缀自动机),我只需要记录下trie上每个点加入它们以后的last,这样每个点加入的时候,从它父亲的记录下来的last开始搞就好了。
方案数就是
这个是后缀自动机的性质,广义当然同样适用。
答案没开long long导致1A失败。
Code:
#include<cstdio> #include<cstring>#define ll long long#define fo(i, x, y) for(int i = x; i <= y; i ++)using namespace std;const int N = 200005;int n, C, c[N], x, y, z, r[N], bz[N];struct edge { int fi[N], nt[N], to[N], t; void link(int x, int y) { nt[++ t] = fi[x], to[t] = y, fi[x] = t; nt[++ t] = fi[y], to[t] = x, fi[y] = t; }} e;struct Trie { int son[N * 20][10], t, last[N * 20]; int is(int x, int c) { if(!son[x][c]) son[x][c] = ++ t; return son[x][c]; }} a;struct suffix_automation { ll ans; int tot, lat, son[N * 20][10], pre[N * 20], step[N * 20]; #define push(u) step[++ tot] = u; void extend(int last, int c) { push(step[last] + 1); int p = last, np = tot; for(; p && !son[p][c]; p = pre[p]) son[p][c] = np; if(!p) pre[np] = 1; else { int q = son[p][c]; if(step[p] + 1 < step[q]) { push(step[p] + 1); int nq = tot; memcpy(son[nq],son[q],sizeof son[q]); pre[nq] = pre[q]; pre[q] = pre[np] = nq; for(; son[p][c] == q; p = pre[p]) son[p][c] = nq; } else pre[np] = q; } last = np; ans += step[last] - step[pre[last]]; lat = last; }} suf;void dg(int x) { bz[x] = 1; int zz = z; for(int i = e.fi[x]; i; i = e.nt[i]) { int y = e.to[i]; if(bz[y]) continue; z = zz; z = a.is(z, c[y]); dg(y); } bz[x] = 0;}void dfs(int x, int y, int pc) { if(x == 0) { a.last[x] = suf.tot = suf.lat = 1; } else { suf.extend(a.last[y], pc); a.last[x] = suf.lat; } fo(i, 0, C - 1) if(a.son[x][i]) { int y = a.son[x][i]; dfs(y, x, i); }}int main() { scanf("%d %d", &n, &C); fo(i, 1, n) scanf("%d", &c[i]); fo(i, 1, n - 1) { scanf("%d %d", &x, &y); e.link(x, y); r[x] ++; r[y] ++; } fo(i, 1, n) if(r[i] == 1) { z = a.is(0, c[i]); dg(i); } dfs(0, 0, 0); printf("%lld", suf.ans);}
阅读全文
1 0
- bzoj 3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
- 【ZJOI2015】诸神眷顾的幻想乡(广义后缀自动机)
- bzoj3926 [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
- 【BZOJ3926】【Zjoi2015】诸神眷顾的幻想乡 广义后缀自动机
- 【BZOJ 3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
- BZOJ3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
- [广义后缀自动机 Trie树] BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡
- BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
- bzoj3926[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机
- [BZOJ]3926 [ZJOI2015] 诸神眷顾的幻想乡 广义后缀自动机
- [BZOJ3926]ZJOI2015诸神眷顾的幻想乡|后缀自动机
- 【BZOJ3926】【Zjoi2015】诸神眷顾的幻想乡 后缀自动机
- 【bzoj3926】[Zjoi2015]诸神眷顾的幻想乡 后缀自动机
- 后缀自动机 【Zjoi2015】诸神眷顾的幻想乡 bzoj3926
- [BZOJ3926][Zjoi2015]诸神眷顾的幻想乡-后缀自动机
- bzoj3926:[Zjoi2015]诸神眷顾的幻想乡(后缀自动机)
- BZOJ3926:[Zjoi2015]诸神眷顾的幻想乡 (后缀自动机)
- BZOJ 3926 Zjoi2015 诸神眷顾的幻想乡 后缀自动机
- 算术逻辑单元之全加器之双重分组跳跃进位链
- 杭电acm P2020绝对值排序
- Windows程序设计:坐标转换
- eclipse如何从官网下载自己想要的版本
- SSH整合
- 【ZJOI2015】诸神眷顾的幻想乡(广义后缀自动机)
- CAXA CAPP工艺图表2018 官方版下载附安装教程
- java知识结构图
- Varinish缓存机制
- 面向组件编程之Unity 4.怎样得到游戏场景中的对象 例如:layer/tag&&SetActive隐藏游戏物体
- Spring Cloud(七)服务网关 Zuul Filter 使用
- 添加voicebox
- pyqt全局鼠标事件/钩子
- Java类的创建: 创建Java的类 ,Java的字段,Java类的方法 – Break易站