zoukankan      html  css  js  c++  java
  • Codeforces Round #326 (Div. 1)

    题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10。

    作法, 利用倍增, ID[j][i] 表示i到i的第2^j个祖先上前10个人, 那么每次询问直接维护就好了,细节好多, 刚开始不知道怎么求ID[j][i]。

    这里把2^j分成两部分, 前2^(j-1)和 后2^(j-1)个, 然后递推的维护。

    感觉树链剖分也可以做, 不知道会不会TLE, 树链剖分的话 线段树的每个点维护10个值, 每次合并就行了。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    const int maxdep = 20;
    int par[maxdep][maxn], dep[maxn], n;
    vector <int> ID[maxdep][maxn], cit[maxn];
    vector <int> G[maxn];
    void init() {
        for (int i = 0; i < maxn; i++) {
            G[i].clear();
            cit[i].clear();
            for (int j = 0; j <  maxdep; j++) {
                ID[j][i].clear();
            }
        }
        memset(par, -1, sizeof (par));
    }
    void update(vector <int> &v1, vector <int> &v2) {
        for (int x: v2) {
            v1.push_back(x);
        }
        sort (v1.begin(), v1.end());
        v1.erase(unique(v1.begin(), v1.end()), v1.end());
        while (v1.size() > 10) {
            v1.pop_back();
        }
    }
    void dfs(int u, int father) {
        par[0][u] = father;
        dep[u] = dep[father] + 1;
        for (int i = u; i <= u; i++) {
            update(ID[0][i], cit[par[0][i]]);
            update(ID[0][i], cit[i]);
            for (int j = 0; j + 1< maxdep; j++) {
                if (~par[j][i]) {
                    par[j+1][i] = par[j][par[j][i]];
                    update(ID[j+1][i], cit[i]);
                    update(ID[j+1][i], ID[j][i]);
                    update(ID[j+1][i], ID[j][par[j][i]]);
                } else {
                    par[j+1][i] = -1;
                }
            }
        }
        for (int v: G[u]) {
            if (v != father) {
                dfs(v, u);
            }
        }
    
    }
    int lca(int u, int v) {
        if (dep[u] > dep[v]) {
            swap(u, v);
        }
        for (int k = 0; k < maxdep; k++) {
            if ((dep[v] - dep[u]) >> k & 1) {
                v = par[k][v];
            }
        }
        if (u == v) {
            return u;
        }
        for (int i = maxdep-1; i >= 0; i--) {
            if (par[i][u] != par[i][v]) {
                u = par[i][u];
                v = par[i][v];
            }
        }
        return par[0][u];
    }
    int anc;
    vector <int> solve(int u, int v) {
        vector <int> res;
        if (u == v) {
            update(res, cit[u]);
        }
        for (int i = maxdep-1; i >= 0; i--) {
            if (~par[i][u] && dep[par[i][u]] >= dep[anc]) {
                update(res, ID[i][u]);
                u = par[i][u];
            }
        }
        for (int i = maxdep-1; i >= 0; i--) {
            if (~par[i][v] && dep[par[i][v]] >= dep[anc]) {
                update(res, ID[i][v]);
                v = par[i][v];
            }
        }
        vector<int> emp;
        update(res, emp);
        return res;
    }
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
        int m, q;
        while (~scanf ("%d%d%d", &n, &m, &q)) {
            init();
            for (int i = 0; i < n-1; i++) {
                int u, v;
                scanf ("%d%d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            for (int i = 0; i < m; i++) {
                int c;
                scanf ("%d", &c);
                if (cit[c].size() < 10) {
                    cit[c].push_back(i+1);
                    ID[0][c].push_back(i+1);
                }
            }
            dfs(1, 0);
            while(q--) {
                int u, v, a;
                scanf ("%d%d%d", &u, &v, &a);
                anc = lca(u, v);
                auto res = solve(u, v);
                int tot = min((int)res.size(), a);
                printf("%d%c", tot, " 
    "[!tot]);
                for (int i = 0; i < min((int)res.size(), a); i++) {
                    printf("%d%c", res[i], " 
    "[i+1==min((int)res.size(), a)]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Cucumber 入门【转】
    unable to find instrumentation target package
    【转】fiddler 请求配置https后出现“你的连接不是私密连接。。。”,处理过程
    DirBuster工具扫描敏感文件
    pycharm常用快捷键
    读取 ini 配置文件
    TypeError: a bytes-like object is required, not 'str'
    日期控件定位处理
    pywin32模块安装
    python:os.path模块常用方法
  • 原文地址:https://www.cnblogs.com/oneshot/p/4896368.html
Copyright © 2011-2022 走看看