rt,树剖求调
#include<bits/stdc++.h>
using namespace std;
const int N = 50005;
int n, m, u, v, cnt, tot, ans;
int top[N], heavy[N], son[N], dfn[N], dep[N], head[N], f[N];
struct edge
{
int to, nxt;
}e[N << 1];
inline void add_edge(int u, int v)
{
e[++tot] = {v, head[u]}, head[u] = tot;
}
inline void dfs1(int u, int fa)
{
f[u] = fa, dep[u] = dep[fa] + 1, son[u] = 1;
for(int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if(v == fa) continue;
dfs1(v, u);
son[u] += son[v];
if(son[v] > son[heavy[u]]) heavy[u] = v;
}
return;
}
inline void dfs2(int u, int tp)
{
dfn[u] = ++cnt, top[u] = tp;
if(heavy[u]) dfs2(heavy[u], tp);
for(int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if(v != f[u] && v != heavy[u]) dfs2(v, v);
}
return;
}
struct node
{
int l, r, tag, maxi;
}tree[N << 4];
inline void push_up(int x)
{
tree[x].maxi = max(tree[x << 1].maxi, tree[x << 1 | 1].maxi);
}
inline void push_down(int x)
{
tree[x << 1].tag += tree[x].tag;
tree[x << 1 | 1].tag += tree[x].tag;
tree[x << 1].maxi += tree[x].tag;
tree[x << 1 | 1].maxi += tree[x].tag;
}
inline void build(int l, int r, int x)
{
tree[x] = {l, r, 0, 0};
if(l == r) return;
int mid = l + r >> 1;
build(l, mid, x << 1);
build(mid + 1, r, x << 1 | 1);
return;
}
inline void update(int l, int r, int x)
{
if(l <= tree[x].l && tree[x].r <= r) return (void) (tree[x].tag++, tree[x].maxi++);
int mid = tree[x].l + tree[x].r >> 1;
push_down(x);
if(l <= mid) update(l, r, x << 1);
if(r > mid) update(l, r, x << 1 | 1);
push_up(x);
return;
}
inline void change(int x, int y)
{
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x, y);
update(dfn[top[x]], dfn[x], 1);
x = f[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
update(dfn[x], dfn[y], 1);
return;
}
int main()
{
// ios :: sync_with_stdio(false);
// cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i < n; i++)
{
cin >> u >> v;
add_edge(u, v);
add_edge(v, u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, n, 1);
while(m--) cin >> u >> v, change(u, v);
cout << tree[1].maxi;
return 0;
}