震惊,某刚学 OI 1 普朗克时间的蒟蒻竟……
查看原帖
震惊,某刚学 OI 1 普朗克时间的蒟蒻竟……
649315
心灵震荡楼主2023/7/25 01:09

rt,树剖求调

#include<bits/stdc++.h>
using namespace std;

const int N = 50005;
int n, m, u, v, cnt, tot, ans;
int top[N], heavy[N], son[N], dfn[N], dep[N], head[N], f[N];

struct edge
{
    int to, nxt;
}e[N << 1];

inline void add_edge(int u, int v)
{
    e[++tot] = {v, head[u]}, head[u] = tot;
}

inline void dfs1(int u, int fa)
{
    f[u] = fa, dep[u] = dep[fa] + 1, son[u] = 1;
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if(v == fa) continue;
        dfs1(v, u);
        son[u] += son[v];
        if(son[v] > son[heavy[u]]) heavy[u] = v;
    }
    return;
}

inline void dfs2(int u, int tp)
{
    dfn[u] = ++cnt, top[u] = tp;
    if(heavy[u]) dfs2(heavy[u], tp);
    for(int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if(v != f[u] && v != heavy[u]) dfs2(v, v);
    }
    return;
}

struct node
{
    int l, r, tag, maxi;
}tree[N << 4];

inline void push_up(int x)
{
    tree[x].maxi = max(tree[x << 1].maxi, tree[x << 1 | 1].maxi);
}

inline void push_down(int x)
{
    tree[x << 1].tag += tree[x].tag;
    tree[x << 1 | 1].tag += tree[x].tag;
    tree[x << 1].maxi += tree[x].tag;
    tree[x << 1 | 1].maxi += tree[x].tag;
}

inline void build(int l, int r, int x)
{
    tree[x] = {l, r, 0, 0};
    if(l == r) return;
    int mid = l + r >> 1;
    build(l, mid, x << 1);
    build(mid + 1, r, x << 1 | 1);
    return;
}

inline void update(int l, int r, int x)
{
    if(l <= tree[x].l && tree[x].r <= r) return (void) (tree[x].tag++, tree[x].maxi++);
    int mid = tree[x].l + tree[x].r >> 1;
    push_down(x);
    if(l <= mid) update(l, r, x << 1);
    if(r > mid) update(l, r, x << 1 | 1);
    push_up(x);
    return;
}

inline void change(int x, int y)
{
    while(top[x] != top[y])
    {
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        update(dfn[top[x]], dfn[x], 1);
        x = f[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    update(dfn[x], dfn[y], 1);
    return;
}

int main()
{
    // ios :: sync_with_stdio(false);
    // cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i < n; i++)
    {
        cin >> u >> v;
        add_edge(u, v);
        add_edge(v, u);
    }
    dfs1(1, 0); 
    dfs2(1, 1);
    build(1, n, 1);
    while(m--) cin >> u >> v, change(u, v);
    cout << tree[1].maxi;
    return 0;
}
2023/7/25 01:09
加载中...