博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bzoj3926 [Zjoi2015]诸神眷顾的幻想乡
阅读量:6935 次
发布时间:2019-06-27

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

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 1241  Solved: 729

Description

 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日。 

粉丝们非常热情,自发组织表演了一系列节目给幽香看。幽香当然也非常高兴啦。 
这时幽香发现了一件非常有趣的事情,太阳花田有n块空地。在过去,幽香为了方便,在这n块空地之间修建了n-1条边将它们连通起来。也就是说,这n块空地形成了一个树的结构。 
有n个粉丝们来到了太阳花田上。为了表达对幽香生日的祝贺,他们选择了c中颜色的衣服,每种颜色恰好可以用一个0到c-1之间的整数来表示。并且每个人都站在一个空地上,每个空地上也只有一个人。这样整个太阳花田就花花绿绿了。幽香看到了,感觉也非常开心。 
粉丝们策划的一个节目是这样的,选中两个粉丝A和B(A和B可以相同),然后A所在的空地到B所在的空地的路径上的粉丝依次跳起来(包括端点),幽香就能看到一个长度为A到B之间路径上的所有粉丝的数目(包括A和B)的颜色序列。一开始大家打算让人一两个粉丝(注意:A,B和B,A是不同的,他们形成的序列刚好相反,比如红绿蓝和蓝绿红)都来一次,但是有人指出这样可能会出现一些一模一样的颜色序列,会导致审美疲劳。 
于是他们想要问题,在这个树上,一共有多少可能的不同的颜色序列(子串)幽香可以看到呢? 
太阳花田的结构比较特殊,只与一个空地相邻的空地数量不超过20个。 

Input

 第一行两个正整数n,c。表示空地数量和颜色数量。 

第二行有n个0到c-1之间,由空格隔开的整数,依次表示第i块空地上的粉丝的衣服颜色。(这里我们按照节点标号从小到大的顺序依次给出每块空地上粉丝的衣服颜色)。 
接下来n-1行,每行两个正整数u,v,表示有一条连接空地u和空地v的边。 

Output

 一行,输出一个整数,表示答案。 

Sample Input

7 3
0 2 1 2 1 0 0
1 2
3 4
3 5
4 6
5 7
2 5

Sample Output

30

HINT

 

对于所有数据,1<=n<=100000, 1<=c<=10。 

对于15%的数据,n<=2000。 
另有5%的数据,所有空地都至多与两个空地相邻。 
另有5%的数据,除一块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻。 
另有5%的数据,除某两块空地与三个空地相邻外,其他空地都分别至多与两个空地相邻

 

字符串 广义后缀自动机

叶子结点不超过20个,事情就好办了。

可以分别从这些叶子结点开始DFS,建20棵trie树,整个树的任何一个子串,都是某个Trie上从一个点到它的一个子孙的路径。把这些trie建到同一个后缀自动机上,统计答案。

 

1 /*by SilverN*/ 2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 using namespace std; 9 const int mxn=100010;10 int read(){11 int x=0,f=1;char ch=getchar();12 while(ch<'0' || ch>'9'){ if(ch=='-')f=-1;ch=getchar();}13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}14 return x*f;15 }16 struct edge{17 int v,nxt;18 }e[mxn<<1];19 int hd[mxn],mct=0;20 void add_edge(int u,int v){21 e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;22 }23 struct SAM{24 int t[mxn*35][10];25 int fa[mxn*35],l[mxn*35];26 int S,cnt,last;27 void init(){S=cnt=last=1;return;}28 int add(int c,int p){29 int np=++cnt;l[np]=l[p]+1;30 for(;p && !t[p][c];p=fa[p])t[p][c]=np;31 if(!p){fa[np]=S;}32 else{33 int q=t[p][c];34 if(l[q]==l[p]+1)fa[np]=q;35 else{36 int nq=++cnt;l[nq]=l[p]+1;37 memcpy(t[nq],t[q],sizeof t[q]);38 fa[nq]=fa[q];39 fa[q]=fa[np]=nq;40 for(;p && t[p][c]==q;p=fa[p])t[p][c]=nq;41 }42 }43 return np;44 }45 void solve(){46 long long res=0;47 for(register int i=1;i<=cnt;i++){48 res+=l[i]-l[fa[i]];49 }50 printf("%lld\n",res);51 return;52 }53 }sa;54 int n,c;55 int co[mxn],in[mxn];56 void DFS(int u,int fa,int id){57 int d=sa.add(co[u],id);58 for(int i=hd[u];i;i=e[i].nxt){59 if(e[i].v==fa)continue;60 DFS(e[i].v,u,d);61 }62 return;63 }64 int main(){65 int i,j,u,v;66 n=read();c=read();67 for(i=1;i<=n;i++)co[i]=read();68 for(i=1;i

 

转载于:https://www.cnblogs.com/SilverNebula/p/6532932.html

你可能感兴趣的文章
mysql导入excel数据
查看>>
Java中写入文件时换行符用"\r\n"、"\n"、"\r"?
查看>>
AIX 命令
查看>>
安装终端服务和终端服务授权,激活终端服务授权
查看>>
朋友,别在降低别人底线或被别人降低底线了!
查看>>
先考学历还是先提升能力?
查看>>
软件项目开发无成熟框架套路之成本代价
查看>>
设计模式(3)-装扮你的类(装饰模式)
查看>>
Android 数字签名学习笔记
查看>>
Linux下Gedit + Gmate ,实用的编辑器
查看>>
OO学习之二——面向对象分析(OOD)的介绍
查看>>
深入python3 (Dive Into Python 3) 在线阅读与下载
查看>>
linux 更改服务的启动顺序
查看>>
【数据结构】除去线性表中的重复数字
查看>>
[原]IE9 DOM的自定义属性问题
查看>>
[CLR via C#]17. 委托
查看>>
Android系统Google Maps开发实例浅析
查看>>
支持向量机(SVM)算法
查看>>
445port入侵具体解释
查看>>
The command 'new_value' for SQLPlus
查看>>