• [CF587C] Duff in the Army


    [CF587C] Duff in the Army - 树上倍增,STL

    Description

    有 n 个城市,由 n-1 条边连接。两个城市之间的道路是唯一的。有 m 个人,住在这 n 个城市中,现在给出 m 个人生活的城市编号。你需要回答,从一个城市 u 到另一个城市 v 的路径中,编号前 a 小的人的编号是哪些。

    Solution

    树上倍增处理路径问题,重载结点加法

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 200005;
    
    int n, m, q;
    vector<int> g[N];
    
    struct Node
    {
        vector<int> a;
        void insert(int x)
        {
            a.push_back(x);
            if (a.size() > 10)
                a.erase(max_element(a.begin(), a.end()));
        }
        vector<int> get(int x)
        {
            vector<int> ans;
            for (int i = 0; i < x; i++)
                ans.push_back(a[i]);
            return ans;
        }
        Node operator+(const Node &rhs) const
        {
            vector<int> ans;
            auto p = a.begin(), q = rhs.a.begin();
            while (ans.size() < 10 && p != a.end() && q != rhs.a.end())
            {
                if (*p < *q)
                    ans.push_back(*p), ++p;
                else
                    ans.push_back(*q), ++q;
            }
            while (ans.size() < 10 && p != a.end())
                ans.push_back(*p), ++p;
            while (ans.size() < 10 && q != rhs.a.end())
                ans.push_back(*q), ++q;
            return {ans};
        }
        Node &operator+=(const Node &rhs)
        {
            (*this) = (*this) + rhs;
        }
    };
    
    int fa[N][20], dep[N];
    Node node[N][20];
    
    void dfs(int p, int from)
    {
        for (int q : g[p])
            if (q != from)
            {
                fa[q][0] = p;
                for (int i = 1; i < 20; i++)
                    fa[q][i] = fa[fa[q][i - 1]][i - 1],
                    node[q][i] = node[q][i - 1] + node[fa[q][i - 1]][i - 1];
                dep[q] = dep[p] + 1;
                dfs(q, p);
            }
    }
    
    Node query(int p, int q)
    {
        Node ans;
        if (dep[p] < dep[q])
            swap(p, q);
        for (int i = 19; i >= 0; i--)
            if (dep[fa[p][i]] >= dep[q])
                ans += node[p][i], p = fa[p][i];
        for (int i = 19; i >= 0; i--)
            if (fa[p][i] != fa[q][i])
                ans += node[p][i], ans += node[q][i], p = fa[p][i], q = fa[q][i];
        if (p != q)
            ans += node[p][0], ans += node[q][0], p = fa[p][0], q = fa[q][0];
        ans += node[p][0];
        return ans;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> n >> m >> q;
        for (int i = 1; i < n; i++)
        {
            int u, v, w;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        for (int i = 1; i <= m; i++)
        {
            int x;
            cin >> x;
            node[x][0].insert(i);
        }
        dep[1] = 1;
        dfs(1, 0);
    
        for (int i = 1; i <= q; i++)
        {
            int u, v, a;
            cin >> u >> v >> a;
            auto ans = query(u, v);
            int sz = min(1ull * ans.a.size(), 1ull * a);
            cout << sz << " ";
            for (int i = 0; i < sz; i++)
                cout << ans.a[i] << " ";
            cout << endl;
        }
    }
    
  • 相关阅读:
    Java单例模式:为什么我强烈推荐你用枚举来实现单例模式
    为什么阿里Java规约要求谨慎修改serialVersionUID字段
    使用MyCat实现MySQL读写分离
    你知道HTTP协议的ETag是干什么的吗?
    在centos7中安装MySQL5.7
    MySQL实现主从复制功能
    Leetcode题目169.求众数(简单)
    Leetcode题目160.相交链表(简单)
    Leetcode题目155.最小栈(简单)
    Leetcode题目152.乘积最大子序列(动态规划-中等)
  • 原文地址:https://www.cnblogs.com/mollnn/p/14359548.html
Copyright © 2020-2023  润新知