树上差分板子

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 50005, M=2*N;
int h[N], to[M], ne[M], tot;
int dep[N],f[N][22];
int n,m,ans,power[N];

void add(int x,int y){
  to[++tot]=y,ne[tot]=h[x],h[x]=tot;
}
void dfs(int u,int fa){ //倍增预处理
  dep[u]=dep[fa]+1, f[u][0]=fa;
  for(int i=1; i<=20; i++) f[u][i]=f[f[u][i-1]][i-1];
  for(int i=h[u]; i; i=ne[i]){
    int v=to[i];
    if(v!=fa) dfs(v,u);
  }
}
int lca(int u,int v){ //倍增求lca
  if(dep[u]<dep[v])swap(u, v);
  for(int i=20; ~i; i--)
    if(dep[f[u][i]]>=dep[v]) u=f[u][i];
  if(u==v) return v;
  for(int i=20; ~i; i--)
    if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
  return f[u][0];
}
void dfs2(int u,int fa){ //统计答案
  for(int i=h[u]; i; i=ne[i]){
    int v=to[i];
    if(v==fa) continue;
    dfs2(v,u);
    power[u]+=power[v];
  }
  ans=max(ans,power[u]);
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1,x,y;i<n;++i){
    scanf("%d%d",&x,&y);
    add(x,y); add(y,x);
  }
  dfs(1,0);
  for(int i=1,x,y; i<=m; ++i){
    scanf("%d%d",&x,&y);
    int l=lca(x,y);
    ++power[x];++power[y]; //树上差分
    --power[l];--power[f[l][0]]; 
  }
  dfs2(1,0);
  printf("%d\n",ans);
}
posted on 2025-10-01 21:49  下头小美  阅读(8)  评论(0)    收藏  举报