博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZJOI 2015 诸神眷顾的幻想乡 题解
阅读量:2305 次
发布时间:2019-05-09

本文共 1159 字,大约阅读时间需要 3 分钟。

题目大意: 给出一棵树,每个点有颜色,任意选出两点从 A A A 走到 B B B 可以得到一个颜色序列,问有多少种不同的颜色序列。

题解

由于叶子节点很少,所以从每个叶子节点出发走到其他的叶子节点,把该路径形成的颜色序列插入到广义SAM中,然后统计有多少个不同的子串即可。

代码如下:

#include 
#include
using namespace std;#define maxn 100010int n,m,a[maxn];struct edge{
int y,next;};edge e[maxn<<1];int first[maxn],len=0;void buildroad(int x,int y){
e[++len]=(edge){
y,first[x]};first[x]=len;}int fa[maxn],du[maxn];struct state{
int len,link,next[10];}st[maxn*40];int id=0,last,now,p,q;void extend(int x){
now=++id; st[now].len=st[last].len+1; for(p=last;p!=-1&&!st[p].next[x];p=st[p].link)st[p].next[x]=now; if(p!=-1) {
q=st[p].next[x]; if(st[p].len+1==st[q].len)st[now].link=q; else {
int clone=++id; st[clone]=st[q];st[clone].len=st[p].len+1; for(;p!=-1&&st[p].next[x]==q;p=st[p].link)st[p].next[x]=clone; st[q].link=st[now].link=clone; } } last=now;}void dfs(int x,bool S){
if(du[x]==1&&!S){
last=0;for(int i=x;i;i=fa[i])extend(a[i]);} else for(int i=first[x];i;i=e[i].next) if(e[i].y!=fa[x])fa[e[i].y]=x,dfs(e[i].y,false);}long long ans=0;int main(){
scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1,x,y;i

转载地址:http://hjnib.baihongyu.com/

你可能感兴趣的文章
352. Data Stream as Disjoint Intervals
查看>>
239. Sliding Window Maximum
查看>>
super & this
查看>>
容器关系:Collection
查看>>
java进阶3——接口和多态
查看>>
java进阶4——内部类
查看>>
java进阶5——日期类、包装类和正则表达式
查看>>
java进阶6——集合
查看>>
java进阶7——异常
查看>>
java进阶8——IO流
查看>>
java进阶9——线程
查看>>
java进阶10——面向网络编程
查看>>
java进阶11——反射&BeanUtils
查看>>
PUSQL学习1——PUSQL 基础
查看>>
JavaWeb文件上传
查看>>
解决tomcat内存不足问题:java.lang.OutOfMemoryError: PermGen space
查看>>
JDBC连接常用数据库的URL
查看>>
iReport 按某个字段(属性)值分页打印
查看>>
矢量图控件VectorDraw使用教程:添加vdFramedControl (Visual C# 2005)
查看>>
矢量图控件VectorDraw使用教程:ActionUtility对象
查看>>