嘟嘟嘟




这题除了暴力我就不会了,感觉得用SAM,但是又和普通的SAM不一样。

看了题解才知道,这东西叫广义后缀自动机。

就是解决例如多个串的本质不同的子串的个数这样的问题。

做法就是每插入完一个串,就重新从根节点开始插入另一个字符串。(但一直只有一个SAM)




对于这道题,可以理解为在trie上建SAM。做法就是在trie上dfs,孩子节点从父亲节点在SAM中的位置插入,代码就是这样:

In void dfs(int now, int _f, int p)
{
p = S.insert(col[now], p);
for(int i = head[now], v; ~i; i = e[i].nxt)
if((v = e[i].to) ^ _f) dfs(v, now, p);
}



因为最多只有20个叶节点,所以我们以每一个叶节点为根,跑一边trie,同时往SAM里插入。这样一定包含了任意一条路径。因为一条路径可以看做从某一个根节点出发的路径的子路径。
最后在后缀自动机上求一下本质不同的子串数目就好了。
```c++
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans = 10) write(x / 10);
putchar(x % 10 + '0');
}

int n, m, col[maxn], du[maxn];

struct Edge

{

int nxt, to;

}e[maxn << 1];

int head[maxn], ecnt = -1;

In void addEdge(int x, int y)

{

e[++ecnt] = (Edge){head[x], y};

head[x] = ecnt;

}

struct Sam

{

int cnt;

int tra[maxn * 40][11], len[maxn * 40], link[maxn * 40];

In void init() {link[cnt = 0] = -1;}

In int insert(int x, int las)

{

int now = ++cnt, p = las;

len[now] = len[las] + 1;

while(~p && !tra[p][x]) tra[p][x] = now, p = link[p];

if(p == -1) link[now] = 0;

else

{

int q = tra[p][x];

if(len[q] == len[p] + 1) link[now] = q;

else

{

int clo = ++cnt;

memcpy(tra[clo], tra[q], sizeof(tra[q]));

len[clo] = len[p] + 1;

link[clo] = link[q], link[q] = link[now] = clo;

while(~p && tra[p][x] == q) tra[p][x] = clo, p = link[p];

}

}

return now;

}

In ll calc()

{

ll ret = 0;

for(int i = 1; i <= cnt; ++i) ret += len[i] - len[link[i]];

return ret;

}

}S;

In void dfs(int now, int _f, int p)

{

p = S.insert(col[now], p);

for(int i = head[now], v; ~i; i = e[i].nxt)

if((v = e[i].to) ^ _f) dfs(v, now, p);

}

int main()

{

Mem(head, -1);

n = read(), m = read();

for(int i = 1; i <= n; ++i) col[i] = read();

for(int i = 1; i < n; ++i)

{

int x = read(), y = read();

addEdge(x, y), addEdge(y, x);

++du[x], ++du[y];

}

S.init();

for(int i = 1; i <= n; ++i) if(du[i] == 1) dfs(i, 0, 0);

write(S.calc()), enter;

return 0;

}

[ZJOI2015]诸神眷顾的幻想乡的更多相关文章

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

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

  2. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对[广义后缀自动机]的一些理解

    先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存 ...

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

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

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

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

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

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

  6. 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机

    [BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝 ...

  7. bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机)

    bzoj3926/luoguP3346 [Zjoi2015]诸神眷顾的幻想乡(trie上构建广义后缀自动机) bzoj Luogu 题解时间 给你个无根trie树(你管这叫trie树?),问你选取一条 ...

  8. BZOJ3926:[ZJOI2015]诸神眷顾的幻想乡(广义SAM)

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

  9. 【刷题】BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡

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

  10. BZOJ3926 Zjoi2015 诸神眷顾的幻想乡【广义后缀自动机】

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

随机推荐

  1. 10个用Console来Debug的高级技巧

    译者按: 我们往往会局限在自己熟悉的知识圈,但也应担偶尔拓展一下,使用一些不常见而又有用的技巧,扩大自己的舒适圈. 原文: 10 Tips for Javascript Debugging Like ...

  2. JavaScript中Map和ForEach的区别

    译者按: 惯用Haskell的我更爱map. 原文: JavaScript — Map vs. ForEach - What’s the difference between Map and ForE ...

  3. intellij error updating changes svn解决办法

    乌龟检出的svn版本为1.8,而1.8在IntelliJ 上跑起来貌似有问题, 经过多次尝试,当Format改为1.7后,问题被解决.

  4. js/es6 元素拖动

    元素事件:鼠标按下事件/鼠标移动事件/鼠标松开事件 元素样式:让元素脱离文档流,采用绝对定位的方式. 一.鼠标按下事件 当鼠标在元素上面按下时,保存元素的初始偏移量和鼠标按下时的坐标,然后在状态变量里 ...

  5. 网页字体在Frontpage2000制作网页中的讲解

    运用HTML,我们可以对字体的大小及字形进行简单的修改,但要进行统一地控制.创建特殊效果,就必须要用到CSS.它能让您更有效地控制网页外观,并可以扩充精确指定网页元素位置,外观以及创建特殊效果的能力. ...

  6. JavaScript 基础(二) - 创建 function 对象的方法, String对象, Array对象

    创建 function 对象的两种方法: 方式一(推荐) function func1(){ alert(123); return 8 } var ret = func1() alert(ret) 方 ...

  7. neutron是一个超级脚本的理解

    1.neutron 是由python写成,表面看有很多的字符串.逻辑处理,除去访问数据库.发送消息队列这些中间件的API调用外,其他部分大部分都在组装成一个shell命令. 并最终调用subproce ...

  8. JS辨别访问浏览器判断是android还是ios系统

    function isIOSOrAndroid() { var browser = { versions: function() { var u = navigator.userAgent, app ...

  9. PyCharm 在PyCharm中使用GitHub

    PyCharm是当前进行Python开发,尤其是Django开发最好的IDE,GitHub是程序员的圣地,几乎人人都在用,就不详细介绍两者了. 本文假设你对PyCharm和Github都有一定的了解, ...

  10. OPPO A57 刷机(官方安装包)+完美Root+ 破解主题+屏蔽Root顶部红色框+NV修复

    朋友说她的手机被被人刷后,有许多预装的软件问我能不能处理下,让我装个纯净版. 开机可以看到预装了许多软件,通常想要删除预装软件就必须Root,于是下载刷机精灵,360刷机大师,线刷包之类的软件Root ...