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

    Codeforces Round #621 (Div. 1 + Div. 2)

    A

    B

    C

    只需计算长度为 (1,2) 的(略)

    D

    E

    大概观察一下,划分可行的条件为:吃同种草的最多有两只,一只左一只右;并且左边走得最远的和右边走得最远的不会碰到。

    枚举左边的羊向右到达的最远点,然后依次考虑每种 (f_i) ,看看能不能往左边、右边塞。最大数量和方案数都可以按照题意模拟求出来

    F

    先预处理两两休息点之间是否能到达。以 (frac{k}{2}) 为最大距离进行多源 (bfs) ,用并查集维护。如果 (k) 为奇数,把所有边长度改为 (2) 且在中间加入额外节点即可。

    对于询问 ((x,y)),先判断 (dist(x,y)leq k),若不满足则必须依靠休息点。那么往各往对方的方向走 (frac{k}{2}) 步,然后判断是否在同一个集合中。

    int n, k, r, a[N], f[N];
    int d[N], fa[N][19], vis[N];
    vector<int> g[N];
    #define pb push_back
    struct node { int u, d; } ; queue<node> q;
    int get (int x) { return x == f[x] ? x : f[x] = get (f[x]); }
    void merge (int x, int y) { f[get (x)] = get (y); }
    void bfs () {
        for (int i = 1; i <= r; ++i)
            q.push ({a[i], 0}), vis[a[i]] = 1;
        while (!q.empty()) {
            node p = q.front (); q.pop ();
            if (p.d == k) continue;
            for (int v : g[p.u]) {
                merge (v, p.u);
                if (!vis[v]) vis[v] = 1, q.push ({v, p.d + 1});
            }
        }
    }
    void dfs (int u, int la) {
        fa[u][0] = la, d[u] = d[la] + 1;
        for (int i = 1; (1 << i) <= d[u]; ++i)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int v : g[u]) if (v != la) dfs (v, u);
    }
    int lca (int x, int y) {
        if (d[x] < d[y]) swap (x, y);
        for (int i = 18; ~i; --i)
            if (d[fa[x][i]] >= d[y]) x = fa[x][i];
        if (x == y) return x;
        for (int i = 18; ~i; --i)
            if (fa[x][i] ^ fa[y][i]) x = fa[x][i], y = fa[y][i];
        return fa[x][0];
    }
    int run (int x, int o) {
        for (int i = 18; ~i; --i)
            if ((1 << i) <= o) o -= (1 << i), x = fa[x][i];
        return x;
    }
    void jump (int &x, int &y, int t) {
        int dx = d[x] - d[t], dy = d[y] - d[t], xx = x;
        x = dx > k ? run (x, k) : run (y, dy - (k - dx));
        y = dy > k ? run (y, k) : run (xx, dx - (k - dy));
    }
    signed main() {
        read (n), read (k), read (r); int tot = n;
        for (int i = 1, u, v; i < n; ++i) {
            read (u), read (v);
            if (k & 1) {
                g[u].pb (++tot), g[tot].pb (u);
                g[v].pb (tot), g[tot].pb (v);
            } else g[u].pb (v), g[v].pb (u);
        }
        n = tot; if (k & 1) k <<= 1; k >>= 1;
        for (int i = 1; i <= r; ++i) read (a[i]);
        for (int i = 1; i <= n; ++i) f[i] = i;
        bfs (), dfs (1, 0);
        int q, x, y; read (q);
        while (q--) {
            read (x), read (y); int t = lca (x, y);
            if (d[x] + d[y] - 2 * d[t] <= k * 2) puts ("YES");
            else jump (x, y, t), puts (get (x) == get (y) ? "YES" : "NO");
        }
        return 0;
    }
    

    G

    。。。

  • 相关阅读:
    泛社交泛泛之交也很重要
    iOS 切后台挂机
    iOS 导航栏translucent用法
    iOS 中UIButton中文字换行
    iOS 给UIimageView添加UITapGestureRecognizer手势点击事件
    iOS15UITableView多了白条,导航栏和Tabbar变成白色和标题变黑处理总结属性变化和原来基本的导航栏属性总结记录(看到就更新)
    iOS延时定时功能
    iOS uiview添加背景图案
    iOS 导航栏返回把样式带回前面怎么办
    iOS 识别图片二维码demo,复制粘贴即用
  • 原文地址:https://www.cnblogs.com/whx666/p/621-div12.html
Copyright © 2011-2022 走看看