Portal:HDU-6065
Test instructions: A root tree with a root node of 1, given an arrangement with a length of N, requires that the permutation be divided into K-segments, defining the value of each segment as the lightest depth of the common ancestor between 22 of the permutation. Minimum total value Required
Exercises
Several properties are listed first:
Property 1. The depth of the common ancestor of all nodes must be the lightest depth of the common ancestor between the 22 nodes
Property 2. If the common ancestor of the first X number of a paragraph is RT, the depth of the public ancestor after the addition of the X+1 Tree is LCA (rt,a[x+1])
Proof: There are only 2 cases where a[x+1] is located in a subtree with RT roots:
①A[X+1] in the sub-tree RT, LCA (rt,a[x+1]) =rt;
②A[X+1] Outside the subtree RT, LCA (Rt,a[x+1]) =lca (any point in the subtree RT, a[x+1])
Property 3. According to the nature of 1 we know that requires a[x+1] and the first X number of public ancestors only require a[x+1] and a[1~x] Any number of LCA can be, we may make this number equals a[x]
Property 4. Adding a number to the section of paragraph p, the value of the interval is not increased. This can also be obtained by the nature of 1.
Define DP[I][J] The minimum value to be spent on the first I-bit cut into the J-segment, the recursive equation can be derived from the above properties:
① adds AI to section k intervals without changing its value: Dp[i][j]=dp[i-1][j]
② adds AI to section K and changes its value as a public ancestor: Dp[i][j]=min (Dp[i][j],dp[i-1][j-1]+deep[a[i])
③ adds AI to section K and updates the depth of the common ancestor: Dp[i][j]=min (Dp[i][j],dp[i-2][j-1]+deep[lca (A[i-1],a[i))) (Use Nature 3)
#include <bits/stdc++.h> using namespace std;
typedef long Long LL;
const int mod = 998244353;
const int MX = 3e5 + 10;
const int inf = 0X3F3F3F3F; struct Edge {int V, NXT;}
E[MX * 2];
int n, M, head[mx], tot;
void Add (int u, int v) {e[tot].v = v;
E[TOT].NXT = Head[u];
Head[u] = tot++;
} int sz, ver[2 * MX], deep[2 * MX], first[mx], dp[2 * mx][30], vis[mx], dir[mx];
void init (int n) {for (int i = 0; I <= N; i++) {vis[i] = 0;
Head[i] =-1;
} tot = Sz = 0;
} void Dfs (int u, int dep) {Vis[u] = true; Ver[++sz] = u; First[u] = sz;
DEEP[SZ] = DEP;
for (int i = head[u]; ~i; i = e[i].nxt) {if (vis[e[i].v]) continue;
int v = E[I].V;
DIR[V] = Dir[u] + 1;
DFS (V, DEP + 1); Ver[++sz] = u;
DEEP[SZ] = DEP;
}} void ST (int n) {for (int i = 1; I <= n; i++) dp[i][0] = i; for (int j = 1; (1 << j) <= N; J + +) {for (int i = 1; i + (1 << J)-1 < = N;
i++) {int a = Dp[i][j-1], B = dp[i + (1 << (j-1))][j-1]; DP[I][J] = Deep[a] < Deep[b]?
A:B;
}}}//The middle part is cross.
int RMQ (int l, int r) {int k = 0;
while ((1 << (k + 1)) <= R-l + 1) k++; int a = Dp[l][k], B = dp[r-(1 << k) + 1][k]; Save the number return Deep[a] < Deep[b]?
A:B;
} int LCA (int u, int v) {int x = First[u], y = first[v];
if (x > Y) Swap (x, y);
int ret = RMQ (x, y);
return Ver[ret];
} void Pre_solve (int n) {dir[1] = 1;
DFS (1, 1);
ST (SZ);
} vector<vector<int> >f;
int A[MX];
int main () {//freopen ("In.txt", "R", stdin);
while (~SCANF ("%d%d", &n, &m)) {init (n);
for (int i = 1; I <= n; i++) scanf ("%d", &a[i]);
for (int i = 1, u, v; i < n; i++) {scanf ("%d%d", &u, &v); Add (U, v);
Add (V, u);
} pre_solve (n);
F.resize (n + 1); for (int i = 0; I <= N;
i++) {f[i].resize (M + 1);
for (int j = 1; j <= M; j + +) f[i][j] = inf;
} F[0][0] = 0;
for (int j = 1; j <= M; j + +) {for (int i = 1; I <= n; i++) {f[i][j] = f[i-1][j];
F[i][j] = min (F[i][j], f[i-1][j-1] + dir[a[i]);
if (i > 1) f[i][j] = min (F[i][j], f[i-2][j-1] + DIR[LCA (A[i], a[i-1]));
}} printf ("%d\n", F[n][m]);
} return 0; }