题意:给定一棵树,每个节点有一个颜色,问树上有多少种子串(定义子串为某两个点上的路径),保证叶子节点数<=20。n<=10^5

题解:

叶子节点小于等于20,考虑将每个叶子节点作为根把树给提起来形成一棵trie,然后定义这棵树的子串为从上到下的一个串(深度从浅到深)。

这样做我们可以发现每个子串必定是某棵trie上的一段直线。统计20棵树的不同子串只需要把它们建到一个自动机上就行了,相当于把20棵trie合并成一棵大的。
对于每个节点x,它贡献的子串数量是max[x]-min[x],又因为min[x]=max[fa]+1,则=max[x]-max[fa],就是step[x]-step[fa];
学会了怎样在sam上插入一颗trie,就直接记录一下父亲在sam上的节点作为p。注意每次都要新开一个点,不然会导致无意义的子串出现。

例如一棵树 (括号内为i颜色)

1(0)

2(1)

3(2)  4(3)

2是1的孩子,3和4都是2的孩子。在以1为根节点的时候插入了这棵trie,在以3为根节点的时候son[root][2]已经存在,如果用它来当现在的点的话就会让一棵trie接在另一棵的末位,导致无意义的子串出现,答案偏大。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; typedef long long LL;
const int N=*;
int n,c,tot,len,last;
int w[N],son[N][],step[N],pre[N],first[N],cnt[N],id[N];
struct node{
int x,y,next;
}a[*N]; void ins(int x,int y)
{
a[++len].x=x;a[len].y=y;
a[len].next=first[x];first[x]=len;
} int add_node(int x)
{
step[++tot]=x;
return tot;
} int extend(int p,int ch)
{
// int np;
// if(son[p][ch]) return son[p][ch];
// else np=add_node(step[p]+1);
int np=add_node(step[p]+);//debug 每次都要新开一个点 while(p && !son[p][ch]) son[p][ch]=np,p=pre[p];
if(p==) pre[np]=;
else
{
int q=son[p][ch];
if(step[q]==step[p]+) pre[np]=q;
else
{
int nq=add_node(step[p]+);
memcpy(son[nq],son[q],sizeof(son[q]));
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
while(son[p][ch]==q) son[p][ch]=nq,p=pre[p];
}
}
last=np;
return np;
} void dfs(int x,int fa,int now)
{
int nt=extend(now,w[x]);
// printf("%d\n",nt);
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y!=fa) dfs(y,x,nt);
}
} int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&c);
for(int i=;i<=n;i++) scanf("%d",&w[i]);
tot=;len=;
memset(son,,sizeof(son));
memset(pre,,sizeof(pre));
memset(cnt,,sizeof(cnt));
memset(first,,sizeof(first));
step[++tot]=;last=;
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
cnt[x]++;cnt[y]++;
}
// for(int i=1;i<=len;i++) printf("%d -- > %d\n",a[i].x,a[i].y);
for(int i=;i<=n;i++)
{
if(cnt[i]==) dfs(i,,);
}
// for(int i=1;i<=tot;i++) printf("%d ",id[i]);printf("\n");
LL ans=;
for(int i=;i<=tot;i++) ans+=(LL)(step[i]-step[pre[i]]);
printf("%lld\n",ans);
return ;
}

【bzoj3926- [Zjoi2015]诸神眷顾的幻想乡】广义sam的更多相关文章

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

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

  2. BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 字符串 SAM

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3926.html 题目传送门 - BZOJ3926 题意 给定一个有 $n$ 个节点,最多只有 $20$ ...

  3. bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机模板

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  4. Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机

    题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...

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

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

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

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

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

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

  8. [BZOJ3926][ZJOI2015]诸神眷顾的幻想乡(后缀自动机)

    日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴啦.  这时幽香发现了一件非常有趣的事情,太阳花田有n块空地.在过去 ...

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

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

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

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

随机推荐

  1. Less入门教程

    http://www.cnblogs.com/fsjohnhuang/p/4187675.html

  2. springmvc基础篇—拆分配置文件

    一般来讲,在企业实际项目中通常会将配置文件设置为两个:spring-mvc.xml.beans.xml,各自管各自的内容,方便管理. 一.在src下增加如下配置文件: <?xml version ...

  3. 免费天气预报API接口

    一.中国气象局(http://www.weather.com.cn) 1.实时接口 http://mobile.weather.com.cn/data/sk/101010100.html http:/ ...

  4. TortoiseSVN的安装使用

    下面分享一篇关于TortoiseSVN的安装以及使用 1.运行TortoiseSVN-1.6.6.17493-win32-svn-1.6.6.msi程序, 开始安装 2.点击Next, 下一步 3.选 ...

  5. 9.0 toast定位+WebDriverWait显示等待

    Toast  判断-----基本操作问题 首先基本操作,进入安卓市场的账号密码页面--- from appium import webdriver from selenium.webdriver.su ...

  6. 4、shader透明测试(AlphaTest)

    主要用于花草树木 用3D的Plane来实现透明的例子: 给Plane先赋予一个带alpha通道的透明图片,但是此图片此时是看不出来是透明的,如下: 现在我们要做的就是显示透明的效果:现在就用到了alp ...

  7. (原创)BFS广度优先算法,看完这篇就够了

    BFS算法 上一篇文章讲解了DFS深度优先遍历的算法,我们说 DFS 顾名思义DEEPTH FIRET,以深度为第一标准来查找,以不撞南墙不回头的态度来发掘每一个点,这个算法思想get到了其实蛮简单. ...

  8. 总结java操作MySQL 即JDBC的使用

    java.sql包中存在DriverManager类,Connection接口,Statement接口和ResultSet接口.类和接口作用如下: DriverManager:主要用于管理驱动程序和连 ...

  9. 语法测试cnblogs使用Markdown

    参考自作业部落Cmd Markdown 编辑器 https://www.zybuluo.com 欢迎使用 Cmd Markdown 编辑阅读器 什么是 Markdown Markdown 是一种方便记 ...

  10. 总结const

    int b; const int  *a=&b; int const * a=&b; int * const a =&b; const int *const a=&b; ...