[Nowcoder] 保护

题意:...
思路:
\(LCA\)乱搞+启发式合并(堆)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
const int maxm = maxn << 2;
int n,m;
int cnt;
int rt[maxn];
int head[maxn];
int dep[maxn];
int f[maxn][26];
vector<int>v[maxn];
struct edge {
    int to;
    int nxt;
}e[maxn << 1];
inline void add(int u,int v) {
    e[++cnt].to = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
    return;
}
struct node {
    int l;
    int r;
    int sum;
}t[maxm];

inline int find_lca(int x,int y) {
    if(dep[x] < dep[y]) swap(x,y);
    int tmp = dep[x] - dep[y];
    for(int i = 20;i >= 0; --i) {
        if(tmp >> i & 1) {
            x = f[x][i];
        }
    }
    if(x == y) return x;
    for(int i = 20; i >= 0; --i) {
        if(f[x][i] != f[y][i]) {
            x = f[x][i];
            y = f[y][i];
        }
    }
    return f[x][0];
}
//calc huan
inline void dfs1(int u,int fa) {
    for(int i = 1;i <= 20; ++i) {
        f[u][i] = f[f[u][i - 1]][i - 1];
    }
    for(int i = head[u];i;i=e[i].nxt) {
        int y = e[i].to;
        if(y != fa) {
            f[y][0] = u;
            dep[y] = dep[u] + 1;
            dfs1(y,u);
        }
    }
}
int tot;
//dui

inline void insert(int l,int r,int &now,int x) {
    if(!now) {
        now = ++tot;
        t[now].sum ++;
    }
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(x <= mid) {
        insert(l,mid,t[now].l,x);
    }
    else insert(mid + 1,r,t[now].r,x);
}

//duihebing
inline int merge(int x,int y) {
    if(!x || !y) {
        return x | y;
    }
    int now = ++tot;
    t[now].l = merge(t[x].l,t[y].l);
    t[now].r = merge(t[x].r,t[y].r);
    t[now].sum = t[x].sum + t[y].sum;
    return now; 
}

inline int query(int l,int r,int now,int x) {
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(t[t[now].l].sum >= x) {
        return query(l,mid,t[now].l,x);
    }
    else {
        return query(mid + 1,r,t[now].r,x - t[t[now].l].sum);
    }
}

inline void dfs2(int x) {
    for(int i = 0;i < v[x].size(); ++i) {
        insert(1,n,rt[x],v[x][i]);
    }
    for(int i = head[x];i;i=e[i].nxt) {
        int y = e[i].to;
        if(y != f[x][0]) {
            dfs2(y);
            rt[x] = merge(rt[x],rt[y]);
        }
    }
}
int x,y,q;
#define pb(x) push_back(x)
int main () {
    scanf("%d %d",&n,&m);
    for(int i = 1;i < n; ++i) {
        scanf("%d %d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dep[1] = 1;
    dfs1(1,0);
    for(int i = 1;i <= m; ++i) {
        scanf("%d %d",&x,&y);
        int FF = find_lca(x,y);
        v[x].pb(dep[FF]);
        v[y].pb(dep[FF]);
    }
    dfs2(1);
    scanf("%d",&q);
    while(q--) {
        scanf("%d %d",&x,&y);
        int tmp = query(1,n,rt[x],y);
        printf("%d\n",max(dep[x] - tmp,0));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/akoasm/p/9614684.html