Construction of bzoj3572 _ virtual tree + lca and bzoj3572 construction of lca

Source: Internet
Author: User

Construction of bzoj3572 _ virtual tree + lca and bzoj3572 construction of lca

World Tree... frozen throne is certainly not a temporary agenda.

I have tried a variety of methods to find things related to the virtual tree. Finally, I understood this question with the help of the big God and DG. Although the gods do not say anything about the virtual tree, I will introduce the application of this question here. (Of course, some great gods do not know what virtual trees are)

For m points of each query, connect them on the original tree to form a subgraph, and add the lca of the m points to the subgraph, if you contract a vertex that is not a query vertex but a vertex whose degree is 2, a virtual tree corresponding to the current query is obtained. (I don't need to care about this name. I just re-constructed a graph)

At this time, we will find that the nodes at both ends of each edge in the virtual tree have their own ownership (this is a nonsense), so we will discuss the attribution of points on this chain, finally, the answer is displayed.

For the process of creating a virtual tree, see the code ...... I also summarized the code at the time. In short, I used the stack to maintain the rightmost link. Every time I updated the elements that were not added and the elements and the stack top, I would just do that.

Ps: it makes sense to see strange variable names.

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define N 300000 + 10#define H 20#define INF 1000000000using namespace std;struct node{    int dist, bel;    node() { }    node(int x, int y)    {        dist = x;        bel = y;    }}g[N];struct edge{    int to, next;}e[2*N];int n, m, q, num, top, ind, cont, p[N], flag[N];int fa[N][H], fa_v[N], r[N], d[N], h[N], s[N], st[N];int sum[N], dfn[N], ans[N], val[N], delta[N];inline bool cmp(int x, int y){ return dfn[x] < dfn[y]; }node min(node a, node b){    if (a.dist == b.dist) return a.bel < b.bel ? a : b;    return a.dist < b.dist ? a : b;}void read(int &x){    x = 0;    char c = getchar();    while(c < '0' || c > '9') c = getchar();    while(c >= '0' && c <= '9')    {        x = 10*x + c - '0';        c = getchar();    }}void add(int x, int y){    e[++num].to = y;    e[num].next = p[x];    p[x] = num;}void init(){    int x, y;    read(n);    for (int i = 1; i < n; ++i)    {        read(x), read(y);        add(x, y);        add(y, x);    }}void bfs(){    queue<int>q;    q.push(1);    fa[1][0] = 1;    flag[1] = 1;    while(!q.empty())    {        int x = q.front();        q.pop();        for (int i = 1; i < H; ++i)        fa[x][i] = fa[fa[x][i-1]][i-1];        for (int i = p[x]; i; i = e[i].next)        {            int k = e[i].to;            if (!flag[k])            {                d[k] = d[x] + 1;                fa[k][0] = x;                flag[k] = 1;                q.push(k);            }        }    }}void dfs(int x){    sum[x] = 1;    dfn[x] = ++ind;    for (int i = p[x]; i; i = e[i].next)    {        int k = e[i].to;        if (k != fa[x][0])        {            dfs(k);            sum[x] += sum[k];        }    }}int lca(int x, int y){    if (d[x] > d[y]) swap(x, y);    int l = x, r = y;    for (int mid = d[r] - d[l], i = 0; mid; ++i, mid >>= 1)    if (mid & 1) r = fa[r][i];    if (l == r) return r;    for (int i = H - 1; i >= 0; i--)    {        if (fa[l][i] == fa[r][i]) continue;        l = fa[l][i], r = fa[r][i];    }    return fa[r][0];}int find(int x, int h){    for (int i = H - 1; i >= 0; i--)    if (d[fa[x][i]] >= h) x = fa[x][i];    return x;}void solve(){    top = cont = 0;    read(m);    for (int i = 1; i <= m; ++i)    {        read(h[i]);        s[++cont] = r[i] = h[i];        g[h[i]] = node(0, h[i]);        ans[h[i]] = 0;    }    sort(h+1, h+m+1, cmp);    for (int i = 1; i <= m; ++i)    {        int x = h[i];        if (!top)        {            st[++top] = x;            fa_v[x] = 0;        }        else        {            int anc = lca(x, st[top]);            while(d[st[top]] > d[anc])            {                if (d[st[top-1]] <= d[anc])                fa_v[st[top]] = anc;                top--;            }            if (st[top] != anc)            {                s[++cont] = anc;                g[anc] = node(INF, 0);                fa_v[anc] = st[top];                st[++top] = anc;            }            fa_v[x] = anc;            st[++top] = x;        }    }    sort(s+1, s+cont+1, cmp);    for (int i = 1; i <= cont; ++i)    {        int x = s[i];        val[x] = sum[x];        if (i > 1) delta[x] = d[x] - d[fa_v[x]];    }    for (int i = cont; i > 1; i--)    {        int x = s[i];        g[fa_v[x]] = min(g[fa_v[x]], node(g[x].dist+delta[x], g[x].bel));    }    for (int i = 2; i <= cont; ++i)    {        int x = s[i];        g[x] = min(g[x], node(g[fa_v[x]].dist+delta[x], g[fa_v[x]].bel));    }    for (int i = 1; i <= cont; ++i)    {        int x = s[i], anc = fa_v[x];        if (i == 1) ans[g[x].bel] += n - sum[x];        else        {            int k = find(x, d[anc]+1);            int del = sum[k] - sum[x];            val[anc] -= sum[k];            if (g[anc].bel == g[x].bel) ans[g[x].bel] += del;            else            {                int mid = d[x] - ((g[x].dist+g[fa_v[x]].dist+delta[x])/2-g[x].dist);                if ((g[x].dist+g[fa_v[x]].dist+delta[x]) % 2 == 0 && g[x].bel > g[fa_v[x]].bel) ++mid;                int tmp = sum[find(x, mid)] - sum[x];                ans[g[x].bel] += tmp;                ans[g[fa_v[x]].bel] += del - tmp;            }        }    }    for (int i = 1; i <= cont; ++i)    ans[g[s[i]].bel] += val[s[i]];    for (int i = 1; i <= m; ++i)    printf("%d ", ans[r[i]]);    putchar('\n');}void deal(){    bfs();    dfs(1);    read(q);    while(q--) solve();}int main(){    init();    deal();    return 0;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.