Codeforces Round #333 (Div. 1) D. Acyclic Organic Compounds trie树合并
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:
![](http://codeforces.com/predownloaded/79/75/7975a6972576c720a1c31d97b2e5d868c2fe77a7.png)
The sets of strings that can be read from individual vertices are:
![](http://codeforces.com/predownloaded/be/62/be620298431b37ceeae5a6d072cb3f97a4441afd.png)
Finally, the values of are:
![](http://codeforces.com/predownloaded/ac/c4/acc451da60f97f7bc4c26c0a17cb35bc255f09e8.png)
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 = 300000 + 10; const int V = N * 15; int n, tot; int ch[V][26], size[V]; int c[N]; int father[N]; vector<int> adj[N]; char label[N]; int merge(int u, int v) { if (u < 0) return v; if (v < 0) return u; int t = tot ++; size[t] = 1; for(int c = 0; c < 26; ++ c) { ch[t][c] = merge(ch[u][c], ch[v][c]); if (ch[t][c] >= 0) { size[t] += size[ch[t][c]]; } } return t; } void dfs(int u) { for(int c = 0; c < 26; ++ c) { ch[u][c] = -1; } for(int e = 0; 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] = 1; for(int x = 0; x < 26; ++ x) { if (ch[u][x] >= 0) { size[u] += size[ch[u][x]]; } } c[u] += size[u]; } void solve() { cin >> n; for(int i = 0; i < n; ++ i) { scanf("%d", c + i); } scanf("%s", label); for(int i = 0; i < n - 1; ++ i) { int u, v; scanf("%d%d", &u, &v); --u, --v; adj[u].push_back(v); adj[v].push_back(u); } father[0] = -1; tot = n; dfs(0); int ret = *max_element(c, c + n); int cnt = 0; for(int i = 0; i < n; ++ i) { if (c[i] == ret) ++ cnt; } cout << ret << ' ' << cnt << endl; } int main() { solve(); return 0; }