题解:比起相同难度的树链剖分,这道题简直是清真到爆,最简单的树剖不解释
代码如下:
#include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define lson root<<1 #define rson root<<1|1 using namespace std; struct node { int lazy,m,l,r; }tr[400040]; int deep[100010],fa[100010],son[100010],size[100010],top[100010],id[100010],c[100010],w[100010],cnt; vector<int> g[100010]; void push_up(int root) { tr[root].m=max(tr[lson].m,tr[rson].m); } void push_down(int root) { tr[lson].m+=tr[root].lazy; tr[lson].lazy+=tr[root].lazy; tr[rson].m+=tr[root].lazy; tr[rson].lazy+=tr[root].lazy; tr[root].lazy=0; } void build(int root,int l,int r) { if(l==r) { tr[root].l=l; tr[root].r=r; tr[root].m=0; return ; } tr[root].l=l; tr[root].r=r; int mid=(l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); push_up(root); } void update(int root,int l,int r,int val) { if(l==tr[root].l&&r==tr[root].r) { tr[root].lazy+=val; tr[root].m+=val; return ; } if(tr[root].lazy) { push_down(root); } int mid=(tr[root].l+tr[root].r)>>1; if(mid<l) { update(rson,l,r,val); } else { if(mid>=r) { update(lson,l,r,val); } else { update(lson,l,mid,val); update(rson,mid+1,r,val); } } push_up(root); } int query(int root,int l,int r) { if(tr[root].l==l&&tr[root].r==r) { return tr[root].m; } if(tr[root].lazy) { push_down(root); } int mid=(tr[root].l+tr[root].r)>>1; if(l>mid) { return query(rson,l,r); } else { if(mid>=r) { return query(lson,l,r); } else { return max(query(lson,l,mid),query(rson,mid+1,r)); } } } void dfs1(int now,int f,int dep) { deep[now]=dep; fa[now]=f; size[now]=1; int maxson=-1; for(int i=0;i<g[now].size();i++) { if(f==g[now][i]) { continue; } dfs1(g[now][i],now,dep+1); size[now]+=size[g[now][i]]; if(size[g[now][i]]>maxson) { son[now]=g[now][i]; maxson=size[g[now][i]]; } } } void dfs2(int now,int topf) { id[now]=++cnt; top[now]=topf; if(!son[now]) { return; } dfs2(son[now],topf); for(int i=0;i<g[now].size();i++) { if(fa[now]==g[now][i]||g[now][i]==son[now]) { continue; } dfs2(g[now][i],g[now][i]); } } void path_update(int x,int y,int val) { while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) { swap(x,y); } update(1,id[top[x]],id[x],1); x=fa[top[x]]; } if(deep[x]>deep[y]) { swap(x,y); } update(1,id[x],id[y],1); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n-1;i++) { int from,to; scanf("%d%d",&from,&to); g[from].push_back(to); g[to].push_back(from); } dfs1(1,0,1); dfs2(1,1); build(1,1,n); for(int i=1;i<=m;i++) { int from,to; scanf("%d%d",&from,&to); path_update(from,to,1); } printf("%d ",query(1,1,n)); }