• Educational Codeforces Round 110 (Rated for Div. 2)【A


    比赛链接:https://codeforces.com/contest/1535

    A. Fair Playoff

    题解

    可以考虑不成立的情况。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int a, b, c, d;
            cin >> a >> b >> c >> d;
            if (min(a, b) > max(c, d) or min(c, d) > max(a, b)) {
                cout << "NO" << "
    ";
            } else {
                cout << "YES" << "
    ";
            }
        }
        return 0;
    }
    

    B. Array Reodering

    题解

    为了尽可能地与 (2a_j) 配对,将因子中含有 (2)(a_i) 排在前面。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            vector<int> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            sort(a.begin(), a.end(), [](int x, int y) {
                if (x % 2 != y % 2) {
                    return x % 2 == 0;
                } else {
                    return x < y;
                }
            });
            int ans = 0;
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    if (gcd(a[i], 2 * a[j]) > 1) {
                        ++ans;
                    }
                }
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    

    C. Unstable String

    题解

    (dp_{i 0/1}) 表示第 (i) 位为 (0/1) 时,以第 (i) 位为终点的 (01) 间隔串的最大长度。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            string s;
            cin >> s;
            long long ans = 0;
            int n = s.size();
            vector<vector<int>> dp(n, vector<int> (2));
            for (int i = 0; i < n; i++) {
                if (i == 0) {
                    if (s[i] == '?') {
                        dp[i][0] = dp[i][1] = 1;
                    } else if (s[i] == '0') {
                        dp[i][0] = 1;
                    } else {
                        dp[i][1] = 1;
                    }
                } else {
                    if (s[i] == '?') {
                        dp[i][0] = dp[i - 1][1] + 1;
                        dp[i][1] = dp[i - 1][0] + 1;
                    } else if (s[i] == '0') {
                        dp[i][0] = dp[i - 1][1] + 1;
                    } else {
                        dp[i][1] = dp[i - 1][0] + 1;
                    }
                }
                ans += max(dp[i][0], dp[i][1]);
            }
            cout << ans << "
    ";
        }
        return 0;
    }
    

    D. Playoff Tournament

    题解

    由于整个比赛状态是一棵满二叉树,在满二叉树中,根节点序号为 (1) ,序号为 (i) 的结点左子结点序号为 (2i) ,右子结点序号为 (2i + 1) ,父结点为 (lfloor frac{i}{2} floor) ,所以可以用数组来实现。

    接下来将叶子结点视为队伍,父结点视为比赛,按照如下方案更新每个结点:

    • 初始时所有叶子结点的方案数赋为 (1) ,代表每支队伍

    • 若某结点对应的比赛结果为 (0) ,则只继承左子结点的方案数

    • 若某结点对应的比赛结果为 (1) ,则只继承右子结点的方案数

    • 若某结点对应的比赛结果为 (?) ,则继承左子结点与右子结点的方案数之和

    同理,在每次询问中,更新某次比赛结果后从其对应的结点往上修改即可。

    Tips

    为了方便在二叉树结点与比赛序号间进行转换,可以将结点 ([2^k-1,1]) 与比赛 ([0,2^k-2]) 依次对应,这样二者始终满足其和为 (2^k - 1) ,同时,为了满足左右子结点大小关系恒定的性质,队伍依次在底端从右往左编号,也因此需要交换比赛结果为 (0)(1) 时的处理方案。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int k;
        cin >> k;
        string s;
        cin >> s;
        const int n = 1 << k;
        vector<int> dp(2 * n);
        for (int i = n; i < 2 * n; i++) {
            dp[i] = 1;
        }
        for (int i = n - 1; i >= 1; i--) {
            dp[i] = s[n - 1 - i] == '0' ? dp[2 * i + 1] : (s[n - 1 - i] == '1' ? dp[2 * i] : dp[2 * i + 1] + dp[2 * i]);
        }
        int q;
        cin >> q;
        while (q--) {
            int p;
            char c;
            cin >> p >> c;
            --p;
            s[p] = c;
            for (int i = n - 1 - p; i != 0; i /= 2) {
                dp[i] = s[n - 1 - i] == '0' ? dp[2 * i + 1] : (s[n - 1 - i] == '1' ? dp[2 * i] : dp[2 * i + 1] + dp[2 * i]);
            }
            cout << dp[1] << "
    ";
        }
        return 0;
    }
    

    E. Gold Transfer

    题解

    由于父结点的花费小于子结点,所以始终选择路径上距离根结点最近且不为空的结点。

    由于路径较长,考虑使用倍增,设 (p_{ij}) 是与结点 (i) 距离为 (2^j) 的结点,那么有状态转移方程: (p_{i j+1} = p_{p_{ij} j}) ,含义为 (2^{j + 1} = 2^j + 2^j)

    之后依次贪心查找即可,每次查找的过程可以看作与最远非空结点间距离的二进制表示。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        constexpr int N = 20;
        int q;
        cin >> q;
        vector<int> a(q + 1), c(q + 1), dep(q + 1);
        vector<vector<int>> p(q + 1, vector<int> (N, -1));
        cin >> a[0] >> c[0];
        for (int i = 1; i <= q; i++) {
            int op;
            cin >> op;
            if (op == 1) {
                cin >> p[i][0];
                dep[i] = dep[p[i][0]] + 1;
                for (int j = 0; (1 << j) <= dep[i]; j++) {
                    p[i][j + 1] = p[p[i][j]][j];
                }
                cin >> a[i] >> c[i];
            } else {
                int v, w;
                cin >> v >> w;
                long long amount = 0, cost = 0;
                while (w > 0 and a[v] > 0) {
                    int u = v;
                    for (int j = N - 1; j >= 0; j--) {
                        if (p[u][j] != -1 and a[p[u][j]] > 0) {
                            u = p[u][j];
                        }
                    }
                    int mi = min(w, a[u]);
                    w -= mi, a[u] -= mi;
                    amount += mi, cost += 1LL * mi * c[u];
                }
                cout << amount << ' ' << cost << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    两线段是否相交模板
    树的距离
    Codeforces Round #369 (Div. 2)-D Directed Roads
    Codeforces Round #369 (Div. 2)-C Coloring Trees
    Codeforces Round #374 (Div. 2)-D Maxim and Array
    zstu-4243 牛吃草
    Codeforces Round #447 (Div. 2)
    zstu 4247-萌新的旅行
    CDQ分治求前缀和
    self.faceshowing = !self.facshowing无效,了,原来set
  • 原文地址:https://www.cnblogs.com/Kanoon/p/14854049.html
Copyright © 2020-2023  润新知