Description
给定一棵有N个点的树,所有节点的权值都为0。
有K次操作,每次指定两个点s,t,将s到t路径上所有点的权值都加一。
请输出K次操作完毕后权值最大的那个点的权值。
Input
第一行,两个整数N(2≤N≤50,000)和K(1≤K≤100,000)。
接下来N-1行,每行两个整数a和b,表示a和b有边(x≠y)。
接下来K行,每行两个整数s和t,表示一个操作的起止点。
Output
一个数表示最大权值点的权值。
Sample Input
5 10
3 4
1 5
4 2
5 4
5 4
5 4
3 5
4 3
4 3
1 3
3 5
5 4
1 5
3 4
Sample Output
9
树剖裸题。
//re去结构体和inline
#include<bits/stdc++.h>
using namespace std;
inline int get(){register int re=0,f=1;register char c;while(c=getchar(),(c>='0'&&c<='9')^1)f=c^'-';while(re=(re<<1)+(re<<3)+(c^48),c=getchar(),(c>='0'&&c<='9'));return f?re:-re;}
const int N = 5e4+10;
#define FOR(i,L,R) for(register int i=(L);i<=(R);++i)
int n,m,cnt;
struct Graph{
int c[N];
vector<int>G[N];
inline void init(){
scanf("%d%d",&n,&m);
FOR(i,1,n-1){
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
}
#define to G[x][i]
int p[N],siz[N],son[N],dep[N];
inline int dfs1(int x,int fa,int depth){
siz[x]=1;
int sz=G[x].size()-1;
FOR(i,0,sz)if(to^fa){
siz[x]+=dfs1(to,p[to]=x,dep[to]=depth+1);
if(siz[son[x]]<siz[to])son[x]=to;
}return siz[x];
}
int rp[N],top[N];
inline void dfs2(int x,int sp){
rp[x]=++cnt;
top[x]=sp;
if(son[x])dfs2(son[x],sp);
int sz=G[x].size()-1;
FOR(i,0,sz)if(to^p[x]&&to^son[x])dfs2(to,to);
}
}g;
struct Seg{
struct tree{
int l,r,k,add;
}a[N*40];
#define ls v<<1
#define rs v<<1|1
void pushdn(int v){
if(a[v].add){
int k=a[v].add;
a[ls].add+=k,a[ls].k+=k;
a[rs].add+=k,a[rs].k+=k;
a[v].add=0;
}
}
void pushup(int v){
a[v].k=max(a[ls].k,a[rs].k);
}
void Addk(int v,int A,int B){
if(a[v].l>B||a[v].r<A)return ;
if(A<=a[v].l&&a[v].r<=B)return ++a[v].k,++a[v].add,void();
pushdn(v);
Addk(ls,A,B),Addk(rs,A,B);
pushup(v);
}
void build(int v,int l,int r){
a[v]=((tree){l,r,0,0});
if(l==r)return ;
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
}
}t;
#define top(a) g.top[a]
#define dep(a) g.dep[a]
#define fa(a) g.p[a]
void Change(int x,int y){
int t1=top(x),t2=top(y);
while(t1^t2){
if(dep(t1)<dep(t2))swap(x,y),swap(t1,t2);
t.Addk(1,g.rp[t1],g.rp[x]);
x=fa(t1);t1=top(x);
}if(dep(x)>dep(y))swap(x,y);
t.Addk(1,g.rp[x],g.rp[y]);
}
int main(){
g.init();
g.dfs1(1,g.p[1]=0,g.dep[1]=1);
g.dfs2(1,1);
t.build(1,1,cnt);
FOR(i,1,m){
int x,y;scanf("%d%d",&x,&y);
Change(x,y);
}cout<<t.a[1].k<<"\n";
return 0;
}