首页 > 其他 > 详细

[CF191C] Fools and Roads - 树上差分,LCA

时间:2021-02-24 23:37:03      阅读:21      评论:0      收藏:0      [点我收藏+]

[CF191C] Fools and Roads - 树上差分,LCA

Description

给出一棵树,给出 m 对点,每对点之间的路径全部加一,最后输出每条边的值。

Solution

剖分求 LCA,然后差分

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

#define int long long
const int N = 1e6 + 5;

vector<int> g[N];
int n, siz[N], wson[N], dep[N], top[N], fa[N], sum[N];

void dfs1(int p, int from)
{
    siz[p] = 1;
    for (int q : g[p])
    {
        if (q == from)
            continue;
        dep[q] = dep[p] + 1;
        fa[q] = p;
        dfs1(q, p);
        siz[p] += siz[q];
        if (siz[q] > siz[wson[p]])
            wson[p] = q;
    }
}

void dfs2(int p, int from)
{
    if (wson[p])
    {
        int q = wson[p];
        top[q] = top[p];
        dfs2(q, p);
    }
    for (int q : g[p])
    {
        if (q == from || q == wson[p])
            continue;
        top[q] = q;
        dfs2(q, p);
    }
}

int lca(int p, int q)
{
    while (top[p] != top[q])
    {
        if (dep[top[p]] < dep[top[q]])
            swap(p, q);
        p = fa[top[p]];
    }
    if (dep[p] > dep[q])
        return q;
    else
        return p;
}

void puttag(int p, int val)
{
    sum[p] += val;
}

void dfs3(int p, int from)
{
    for (int q : g[p])
    {
        if (q == from)
            continue;
        dfs3(q, p);
        sum[p] += sum[q];
    }
}

signed main()
{
    ios::sync_with_stdio(false);

    cin >> n;
    vector<pair<int, int>> edge(n + 2);
    for (int i = 1; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
        edge[i] = {x, y};
    }

    dfs1(1, 0);
    top[1] = 1;
    dfs2(1, 0);

    int k;
    cin >> k;
    for (int i = 1; i <= k; i++)
    {
        int x, y;
        cin >> x >> y;
        int l = lca(x, y);
        puttag(x, +1);
        puttag(y, +1);
        puttag(l, -2);
    }

    dfs3(1, 0);

    for (int i = 1; i < n; i++)
    {
        auto [x, y] = edge[i];
        if (dep[x] > dep[y])
            cout << sum[x] << " ";
        else
            cout << sum[y] << " ";
    }
}

[CF191C] Fools and Roads - 树上差分,LCA

原文:https://www.cnblogs.com/mollnn/p/14442462.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!