zoukankan      html  css  js  c++  java
  • Codeforces Round #736 (Div. 2)【ABCD】

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

    A. Gregor and Cryptography

    题解

    构造。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) {
            int p;
            cin >> p;
            cout << 2 << ' ' << (p - 1) << "
    ";
        }
        return 0;
    }
    

    B. Gregor and the Pawn Game

    题解

    贪心,尽可能地靠一边放。

    代码

    #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<string> MP(2);
            for (int i = 0; i < 2; i++) {
                cin >> MP[i];
            }
            vector<bool> vis(n);
            for (int i = 0; i < n; i++) {
                if (MP[1][i] == '0') {
                    continue;
                }
                if (i - 1 >= 0 and MP[0][i - 1] == '1' and not vis[i - 1]) {
                    vis[i - 1] = true;
                } else if (MP[0][i] == '0' and not vis[i]) {
                    vis[i] = true;
                } else if (i + 1 < n and MP[0][i + 1] == '1' and not vis[i + 1]) {
                    vis[i + 1] = true;
                }
            }
            cout << count(vis.begin(), vis.end(), true) << "
    ";
        }
        return 0;
    }
    

    C. Web of Lies

    题解

    类似拓扑排序的思想,将无向边转化为有向边,假设由较小点指向较大点,每次询问即统计出度为 0 的点。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n, m;
        cin >> n >> m;
        vector<int> out(n);
        set<int> st;
        auto opt = [&](bool add) {
            int u, v;
            cin >> u >> v;
            --u, --v;
            out[min(u, v)] += add ? 1 : -1;
            st.erase(u), st.erase(v);
            if (out[u] == 0) {
                st.insert(u);
            }
            if (out[v] == 0) {
                st.insert(v);
            }
        };
        for (int i = 0; i < m; i++) {
            opt(true);
        }
        for (int u = 0; u < n; u++) {
            if (out[u] == 0) {
                st.insert(u);
            }
        }
        int q;
        cin >> q;
        while (q--) {
            int op;
            cin >> op;
            if (op == 1) {
                opt(true);
            } else if (op == 2) {
                opt(false);
            } else {
                cout << st.size() << "
    ";
            }
        }
        return 0;
    }
    

    D. Integers Have Friends

    题解

    不妨先考察较小的情况,如果两个数 (a)​ 和 (b)​ 同余,它们与余数 (m)​ 的关系。

    假设 (a lt b) ,易得:

    (a = a)

    (b = a + (b - a))

    (a)(b)(m) 取余即:

    (a mod m)

    (a mod m + (b - a) mod m)

    所以,若 (a)(b) 同余,那么 ((b - a) mod m = 0) ,即 (m)((b - a))​ 的因子。

    推广到 (n)​​​ 个数同余的情况,可以看作 (n - 1)​​​ 对相邻的数, (m)​​​ 同为 (n - 1)​ 对相邻数之差的因子。

    所以,问题即转化成了在 (b_i = |a_{i + 1} - a_i|) 中寻找 (gcd gt 1)​​ 的最长区间。

    可以枚举区间的左端点,然后用双指针或二分结合 (st)​​​ 表计算区间的右端点。

    代码一

    #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<long long> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            if (n == 1) {
                cout << 1 << "
    ";
                continue;
            }
            vector<long long> b(n - 1);
            for (int i = 0; i < n - 1; i++) {
                b[i] = abs(a[i + 1] - a[i]);
            }
            const int logn = __lg(n) + 1;
            vector<vector<long long>> spt(n - 1, vector<long long> (logn));
            for (int i = 0; i < n - 1; i++) {
                spt[i][0] = b[i];
            }
            for (int j = 1; j < logn; j++) {
                for (int i = 0; i + (1 << j) - 1 < n - 1; i++) {
                    spt[i][j] = gcd(spt[i][j - 1], spt[i + (1 << (j - 1))][j - 1]);
                }
            }
            auto query = [&](int l, int r) {
                int ep = __lg(r - l + 1);
                return gcd(spt[l][ep], spt[r - (1 << ep) + 1][ep]);
            };
            int ans = 0;
            for (int i = 0, j = -1; i < n - 1; i++) {
                while (j + 1 < n - 1 and query(i, j + 1) > 1) {
                    ++j;
                }
                if (i <= j) {
                    ans = max(ans, j - i + 1);
                }
                j = max(j, i);
            }
            cout << ans + 1 << "
    ";
        }
        return 0;
    }
    

    代码二

    #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<long long> a(n);
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            if (n == 1) {
                cout << 1 << "
    ";
                continue;
            }
            vector<long long> b(n - 1);
            for (int i = 0; i < n - 1; i++) {
                b[i] = abs(a[i + 1] - a[i]);
            }
            const int logn = __lg(n) + 1;
            vector<vector<long long>> spt(n - 1, vector<long long> (logn));
            for (int i = 0; i < n - 1; i++) {
                spt[i][0] = b[i];
            }
            for (int j = 1; j < logn; j++) {
                for (int i = 0; i + (1 << j) - 1 < n - 1; i++) {
                    spt[i][j] = gcd(spt[i][j - 1], spt[i + (1 << (j - 1))][j - 1]);
                }
            }
            auto query = [&](int l, int r) {
                int ep = __lg(r - l + 1);
                return gcd(spt[l][ep], spt[r - (1 << ep) + 1][ep]);
            };
            int ans = 0;
            for (int i = 0; i < n - 1; i++) {
                int l = i, r = n - 2;
                while (l < r) {
                    int mid = (l + r + 1) / 2;
                    if (query(i, mid) > 1) {
                        l = mid;
                    } else {
                        r = mid - 1;
                    }
                }
                if (query(i, r) > 1) {
                    ans = max(ans, r - i + 1);
                }
            }
            cout << ans + 1 << "
    ";
        }
        return 0;
    }
    

    参考

    https://oi-wiki.org/ds/sparse-table/

    https://codeforces.com/contest/1548/submission/124526158

  • 相关阅读:
    HTML3 / 4 / 4.1 / 5 版本升级过程中,变化是怎么样的
    HTML head内所有标签,及其作用
    HTML 和 XHTML和区别
    HTML DOCTYPE 都有哪些,它们之前的区别和用途分别是什么?
    eclipse中英文切换--四种方式
    Eclipse Class Decompiler---Java反编译插件
    jdk历史版本下载
    eclipse优化(部分)
    博客迁移到github
    JavaScript:同步、异步和事件循环
  • 原文地址:https://www.cnblogs.com/Kanoon/p/15095277.html
Copyright © 2011-2022 走看看