这题 LCA 就可以鬼知道我为啥要写树剖
//树剖做法
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAX=4e5+9;
struct Edge{
int nxt,to;
}edge[MAX];
int num_edge=0,head[MAX];
struct Tree{
int ls,rs;
int maxn,tag;
}tree[MAX];
int num_tree=1;
int num_T=0,dep[MAX],f[MAX],top[MAX],Tid[MAX],siz[MAX],heavy[MAX];
int n,m;
void add_edge(int from,int to){
edge[++num_edge]=(Edge){head[from],to};
head[from]=num_edge;
}void push_up(int now){
tree[now].maxn=max(tree[tree[now].ls].maxn,tree[tree[now].rs].maxn);
}void push_down(int now,int l,int r){
int mid=(l+r)/2;
tree[tree[now].ls].tag+=tree[now].tag;
tree[tree[now].ls].maxn+=(mid-l+1)*tree[now].tag;
tree[tree[now].rs].tag+=tree[now].tag;
tree[tree[now].rs].maxn+=(r-mid)*tree[now].tag;
tree[now].tag=0;
}void build(int now,int l,int r){
if(l==r){
tree[now].maxn=0;
return;
}int mid=(l+r)/2;
tree[now].ls=++num_tree;
tree[now].rs=++num_tree;
build(tree[now].ls,l,mid);
build(tree[now].rs,mid+1,r);
push_up(now);
}void update(int now,int l,int r,int lx,int rx,int k){
if(lx>r&&rx<l)return;
if(lx<=l&&r<=rx){
tree[now].maxn+=(r-l+1)*k;
tree[now].tag+=k;
return;
}int mid=(l+r)/2;
push_down(now,l,r);
if(lx<=mid)update(tree[now].ls,l,mid,lx,rx,k);
if(rx>mid)update(tree[now].rs,mid+1,r,lx,rx,k);
push_up(now);
}int querymax(int now,int l,int r,int lx,int rx){
if(lx>r&&rx<l)return -1;
if(lx<=l&&r<=rx){
return tree[now].maxn;
}int mid=(l+r)/2,ans=-1;
push_down(now,l,r);
if(lx<=mid)ans=max(ans,querymax(tree[now].ls,l,mid,lx,rx));
if(rx>mid)ans=max(ans,querymax(tree[now].rs,mid+1,r,lx,rx));
return ans;
}void dfs1(int now,int fa){
f[now]=fa;
siz[now]=1;
dep[now]=dep[fa]+1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa)continue;
dfs1(to,now);
siz[now]+=siz[to];
if(siz[to]>siz[heavy[now]])heavy[now]=to;
}
}void dfs2(int now,int tp){
top[now]=tp;
Tid[now]=++num_T;
if(heavy[now])dfs2(heavy[now],tp);
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==f[now]||to==heavy[now])continue;
dfs2(to,to);
}
}void Tupdate(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,n,Tid[top[x]],Tid[x],1);
x=f[top[x]];
}if(dep[x]>dep[y])swap(x,y);
update(1,1,n,Tid[x],Tid[y],1);
}
//int Tquerymax(int x,int y){
// int ans=-1;
// while(top[x]!=top[y]){
// if(dep[top[x]]<dep[top[y]])swap(x,y);
// ans=max(ans,querymax(1,1,n,Tid[top[x]],Tid[x]));
// x=f[top[x]];
// }if(dep[x]>dep[y])swap(x,y);
// ans=max(ans,querymax(1,1,n,Tid[x],Tid[y]));
// return ans;
//}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d %d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d %d",&u,&v);
Tupdate(u,v);
}printf("%d\n",querymax(1,1,n,1,n));
return 0;
}
答案出错,不知道哪错了,求助qwq