思路

这个题哪里有那么费脑筋
我们可以树链剖分嘛LCT昨天学的时候睡着了,不是太会
两遍dfs+一个5行的BIT
其实树链剖分学好了对倍增和LCT理解上都有好处
一条路径上的修改
由于一条剖出来的链是连续的,我们要选择数据结构维护
不过这里不用维护太多东西,只是区间+1
我们可以选择常数小,好写的树状数组(从50行的线段树变成5行的
BIT)
而且使得\(O(nlog_{2})\)的算法跑的并不慢
具体就是用差分思想,修改区间[L,R]时
$[1,R] +1 $ \([1,L-1] -1\)达到修改的目的
最后查询时
直接每次查询[1,i]的值就可得到i的最终压力值

代码

#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=2e5+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
vector<int> G[maxn];
int n,m,top[maxn],f[maxn],siz[maxn],idx[maxn],cnt,son[maxn],dep[maxn];
void dfs1(int u,int fa) {
    f[u]=fa;
    siz[u]=1;
    dep[u]=dep[fa]+1;
    for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) {
        if(*it==fa) continue;
        dfs1(*it,u);
        siz[u]+=siz[*it];
        if(siz[son[u]] < siz[*it]) son[u]=*it;
    }
}
void dfs2(int u,int topf) {
    idx[u]=++cnt;
    top[u]=topf;
    if(!son[u]) return;
    dfs2(son[u],topf);
    for(std::vector<int>::iterator it=G[u].begin();it!=G[u].end();++it)
        if(!idx[*it]) dfs2(*it,*it);
}
namespace BIT {
    int sum[maxn];
    int lowbit(int x) {return x&-x;}
    void add(int x,int k) {for(int i=x;i<=n;i+=lowbit(i)) sum[i]+=k;}
    int query(int x) {int ans=0;for(int i=x;i>=1;i-=lowbit(i)) ans+=sum[i];return ans;}
    void modify(int x,int y) {if(x!=n)add(y+1,-1);add(x,1);}
}
void change(int x,int y) {
    while(top[x]!=top[y]) {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        BIT::modify(idx[top[x]],idx[x]);
        x=f[top[x]];
    }
    if(dep[x] > dep[y]) swap(x,y);
    BIT::modify(idx[x],idx[y]);
}
int main() {
    n=read(),m=read();
    FOR(i,2,n) {
        int x=read(),y=read();
        G[x].push_back(y),G[y].push_back(x);
    }
    dfs1(1,0);dfs2(1,1);
    FOR(i,1,m) change(read(),read());
    int ans=0;
    FOR(i,1,n) ans=max(ans,BIT::query(i));
    cout<<ans<<"\n";
    return 0;
}