trie合并的裸题...因为最多只有n个点,所以最多合并n次,复杂度$O(N*26)$。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int maxn=, inf=1e9;
struct poi{int too, pre;}e[maxn<<];
struct tjm{int nxt[], size;}tree[maxn];
int n, x, y, ans, cnt, tot;
int last[maxn], c[maxn];
char s[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
void merge(int &x, int y)
{
if(!x || !y) {x+=y; return;}
tree[x].size=;
for(int i=;i<;i++)
merge(tree[x].nxt[i], tree[y].nxt[i]), tree[x].size+=tree[tree[x].nxt[i]].size;
}
void dfs(int x, int fa)
{
tree[x].size=;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa)
{
dfs(too, x); int tmp=tree[tree[x].nxt[s[e[i].too]-'a']].size;
merge(tree[x].nxt[s[e[i].too]-'a'], e[i].too);
tree[x].size+=tree[tree[x].nxt[s[e[i].too]-'a']].size-tmp;
}
if(tree[x].size+c[x]>ans) ans=tree[x].size+c[x], cnt=;
else if(tree[x].size+c[x]==ans) cnt++;
}
int main()
{
read(n);
for(int i=;i<=n;i++) read(c[i]); scanf("%s", s+);
for(int i=;i<n;i++) read(x), read(y), add(x, y), add(y, x);
dfs(, ); printf("%d\n%d", ans, cnt);
}

  当然还可以直接上哈希+平衡树+启发式合并,用set自带去重就好了,复杂度$O(Nlog^2N)$。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<set>
#define ll long long
using namespace std;
const int maxn=, inf=1e9;
const ll mod=;
typedef set<ll>::iterator ddq;
struct poi{int too, pre;}e[maxn<<];
int n, x, y, tot, ans, ansnum;
int last[maxn], c[maxn], root[maxn];
ll hs[maxn];
char ch[maxn];
set<ll>s[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
inline int merge(int x, int y)
{
if(s[x].size()<s[y].size()) swap(x, y);
for(ddq ity=s[y].begin();ity!=s[y].end();ity++) s[x].insert(*ity);
s[y].clear(); return x;
}
void dfs(int x, int fa)
{
hs[x]=(hs[fa]*+ch[x]-'a'+)%mod;
s[x].insert(hs[x]); root[x]=x;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa)
{
dfs(too, x);
root[x]=merge(root[x], root[too]);
}
int size=s[root[x]].size();
if(size+c[x]>ans) ans=size+c[x], ansnum=;
else if(size+c[x]==ans) ansnum++;
}
int main()
{
read(n);
for(int i=;i<=n;i++) read(c[i]);
scanf("%s", ch+);
for(int i=;i<n;i++) read(x), read(y), add(x, y), add(y, x);
dfs(, ); printf("%d\n%d", ans, ansnum);
}

  当然还可以hash之后用dsu on tree,复杂度$O(NlogN)$。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=, inf=1e9;
const ll mod=;
struct poi{int too, pre;}e[maxn<<];
int n, x, y, N, tot, sum, skip, ANS, ANSNUM;
int c[maxn], last[maxn], son[maxn], size[maxn], cnt[maxn], ans[maxn];
ll b[maxn], hs[maxn];
char s[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
void dfs1(int x, int fa)
{
size[x]=; b[x]=hs[x]=(hs[fa]*+s[x]-'a'+)%mod;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa)
{
dfs1(too, x);
size[x]+=size[too];
if(size[too]>size[son[x]]) son[x]=too;
}
}
void update(int x, int fa, int delta)
{
if(delta==) sum+=(!cnt[hs[x]]);
cnt[hs[x]]+=delta;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa && too!=skip) update(too, x, delta);
}
void dfs2(int x, int fa, bool heavy)
{
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa && too!=son[x]) dfs2(too, x, );
if(son[x]) dfs2(son[x], x, ), skip=son[x];
update(x, fa, ); ans[x]=sum; skip=;
if(!heavy) update(x, fa, -), sum=;
if(ans[x]+c[x]>ANS) ANS=ans[x]+c[x], ANSNUM=;
else if(ans[x]+c[x]==ANS) ANSNUM++;
}
int main()
{
read(n);
for(int i=;i<=n;i++) read(c[i]);
scanf("%s", s+);
for(int i=;i<n;i++) read(x), read(y), add(x, y), add(y, x);
dfs1(, );
N=n; sort(b+, b++N); N=unique(b+, b++N)-b-;
for(int i=;i<=n;i++) hs[i]=lower_bound(b+, b++N, hs[i])-b;
dfs2(, , ); printf("%d\n%d", ANS, ANSNUM);
}

  还可以hash之后写线段树合并,复杂度$O(NlogN)$。(真的懒得写了T T

Codeforces 601D. Acyclic Organic Compounds(四个愿望一次满足)的更多相关文章

  1. 【CodeForces】601 D. Acyclic Organic Compounds

    [题目]D. Acyclic Organic Compounds [题意]给定一棵带点权树,每个点有一个字符,定义一个结点的字符串数为往下延伸能得到的不重复字符串数,求min(点权+字符串数),n&l ...

  2. Codeforces Round #333 (Div. 1) D. Acyclic Organic Compounds trie树合并

    D. Acyclic Organic Compounds   You are given a tree T with n vertices (numbered 1 through n) and a l ...

  3. Acyclic Organic Compounds

    题意: 给一以1为根的字符树,给出每个节点的字符与权值,记 $diff_{x}$ 为从 $x$ 出发向下走,能走到多少不同的字符串,求问最大的$diff_{x} + c_{x}$,并求有多少个 $di ...

  4. CF601D:Acyclic Organic Compounds

    给n<=300000的树,每个点上有一个字母,一个点的权值为:从该点出发向下走到任意节点停下形成的不同字符串的数量,问最大权值. 题目本身还有一些奇怪要求在此忽略.. Trie合并的模板题. # ...

  5. CF数据结构练习

    1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...

  6. cf Round 601

    A.The Two Routes(BFS) 给出n个城镇,有m条铁路,铁路的补图是公路,汽车和火车同时从1出发,通过每条路的时间为1,不能同时到达除了1和n的其它点,问他们到达n点最少要用多长时间. ...

  7. Codeforces Round #269 (Div. 2) A,B,C,D

    CodeForces - 471A 首先要有四个数相等,然后剩下两个数不同就是Bear,否则就是Elephant. #include <bits/stdc++.h> using names ...

  8. 我为什么要进国企----HP大中华区总裁孙振耀退休感言

    一.关于工作与生活 我有个有趣的观察,外企公司多的是25-35岁的白领,40岁以上的员工很少,二三十岁的外企员工是意气风发的,但外企公司40岁附近的经理人是很尴尬的.我见过的40岁附近的外企经理人大多 ...

  9. 转(HP大中华区总裁孙振耀退休感言)

    开篇转发一篇好文,苦闷,消沉,寂寞,堕落的时候看看. 发现这篇文章是09年之前就有人转发到自己博客了.放到自己的地盘,容易记起有这么个心灵鸡汤.   一.关于工作与生活 我有个有趣的观察,外企公司多的 ...

随机推荐

  1. zookeeper 简单小节

    1. ZooKeeper 是什么 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务.主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储 ...

  2. KEIL5的安装

    安装注意事项 1.最好不要安装在带有中文路径的文件夹. 2.试用版的Keil MDK只能编译32K以下的代码,代码大于32K只能使用正版或破解版才能编译通过. 安装MKD 这里选择MKD512A版本安 ...

  3. Jmeter接口测试(三)接口测试实践

    Jmeter 脚本编写一般分五个步骤: 1. 添加线程组 2. 添加 http 请求 3. 在 http 请求中写入接入 url.路径.请求方式和参数 4. 添加查看结果树 5. 调用接口.查看返回值 ...

  4. Zookeeper--java操作zookeeper

    如果是使用java操作zookeeper,zookeeper的javaclient 使我们更轻松的去对zookeeper进行各种操作,我们引入zookeeper-3.4.5.jar 和 zkclien ...

  5. VS默认的类前缀(访问控制符)是internal

    VS默认的类前缀(访问控制符)是internal 大家都知道VS默认新建的class的时候,class前面是什么都没有的,按照规则,这个class的可见性是internal,但是说实话,很多人包括我在 ...

  6. ECharts模块化使用5分钟上手

    什么是EChats? 一句话: 一个数据可视化(图表)Javascript框架,详细?移步这里,类似(推荐)的有 HighCharts,其他? 嗯,先看看吧-- 快速上手: 模块化单文件引入(推荐). ...

  7. “Hello World!”团队第五周第五次会议

    博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.checkout&push代码 一.会议时间 2017年11月14日  ...

  8. “Hello World!”团队第九次会议

    今天是我们团队“Hello World!”团队召开的第九次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 20 ...

  9. 20172330 2017-2018-1 《Java程序设计》第十周学习总结

    20172330 2017-2018-1 <程序设计与数据结构>第十周学习总结 教材学习内容总结 本周的学习内容为集合 集合 对象具有定义良好的接口,从而成为一种实现集合的完善体制. 动态 ...

  10. C++中使用内存映射文件处理大文件

    引言 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile().WriteFile().ReadFile() ...