You are given a tree T with n vertices (numbered 1 through n) and a letter in each vertex. The tree is rooted at vertex 1.
Let's look at the subtree Tv of some vertex v. It is possible to read a string along each simple path starting at v and ending at some vertex in Tv (possibly v itself). Let's denote the number of distinct strings which can be read this way as .
Also, there's a number cv assigned to each vertex v. We are interested in vertices with the maximum value of .
You should compute two statistics: the maximum value of and the number of vertices v with the maximum
.
The first line of the input contains one integer n (1 ≤ n ≤ 300 000) — the number of vertices of the tree.
The second line contains n space-separated integers ci (0 ≤ ci ≤ 109).
The third line contains a string s consisting of n lowercase English letters — the i-th character of this string is the letter in vertex i.
The following n - 1 lines describe the tree T. Each of them contains two space-separated integers u and v (1 ≤ u, v ≤ n) indicating an edge between vertices u and v.
It's guaranteed that the input will describe a tree.
Print two lines.
On the first line, print over all 1 ≤ i ≤ n.
On the second line, print the number of vertices v for which .
10
1 2 7 20 20 30 40 50 50 50
cacabbcddd
1 2
6 8
7 2
6 2
5 4
5 9
3 10
2 5
2 3
51
3
In the first sample, the tree looks like this:
The sets of strings that can be read from individual vertices are:
Finally, the values of are:
In the second sample, the values of are (5, 4, 2, 1, 1, 1). The distinct strings read in T2 are
; note that
can be read down to vertices 3 or 4.
trie树合并
比较考验代码能力
显然我就比较low
这份代码是cf抠来的
#include<iostream>
#include<vector>
#include<cassert>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; const int N = + ;
const int V = N * ; int n, tot;
int ch[V][], size[V];
int c[N];
int father[N];
vector<int> adj[N];
char label[N]; int merge(int u, int v)
{
if (u < ) return v;
if (v < ) return u;
int t = tot ++;
size[t] = ;
for(int c = ; c < ; ++ c) {
ch[t][c] = merge(ch[u][c], ch[v][c]);
if (ch[t][c] >= ) {
size[t] += size[ch[t][c]];
}
}
return t;
} void dfs(int u)
{
for(int c = ; c < ; ++ c) {
ch[u][c] = -;
}
for(int e = ; e < adj[u].size(); ++e) {
int v = adj[u][e];
if (v == father[u]) continue;
father[v] = u;
dfs(v);
int lab = label[v] - 'a';
ch[u][lab] = merge(ch[u][lab], v);
}
size[u] = ;
for(int x = ; x < ; ++ x) {
if (ch[u][x] >= ) {
size[u] += size[ch[u][x]];
}
}
c[u] += size[u];
} void solve()
{
cin >> n;
for(int i = ; i < n; ++ i) {
scanf("%d", c + i);
}
scanf("%s", label);
for(int i = ; i < n - ; ++ i) {
int u, v;
scanf("%d%d", &u, &v);
--u, --v;
adj[u].push_back(v);
adj[v].push_back(u);
}
father[] = -;
tot = n;
dfs();
int ret = *max_element(c, c + n);
int cnt = ;
for(int i = ; i < n; ++ i) {
if (c[i] == ret) ++ cnt;
}
cout << ret << ' ' << cnt << endl;
} int main()
{
solve();
return ;
}