Codeforces Round #862 (Div. 2) (题解)

Codeforces Round #862 (Div. 2) (题解)

CodeForces1805A

原题链接

思路:

b数组的XOR = a数组的XOR xor x的个数(即x xor x xor …),所以我们只需要计算a数组的XOR,然后看一下x的个数即可。x的个数取决于n的个数

  1. n为奇数,则最后必剩余1个x(x xor x两两抵消).x 取a数组XOR的值即可
  2. n为偶数, 则最后x全部被抵消掉。如果a数组XOR的值不为0,则无解,输出-1。否则,x取任意值(这里取x为0)
#include 

using i64 = long long;
using PII = std::pair<int,int>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    int x;
    std::cin >> x;
    int res = x;
    for (int i = 0; i < n - 1; i ++) {
        std::cin >> x;
        res ^= x;
    }
    if (n % 2 == 0) {
        if (!res) {
            std::cout << "0\n";
        } else {
            std::cout << "-1\n";
        }
    } else {
        std::cout << res << "\n";    
    }
    
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}



CodeForces1805B

原题链接

思路:

记录每个字母最后出现的下标位置,找到最小字典序的字母,将其放在第一个的位置,其他字母后移。

#include 

using i64 = long long;
using PII = std::pair<int,int>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    std::string s;
    std::cin >> s;

    std::map<char,int> mp;
    for (int i = 0; i < n; i ++) {
        mp[s[i]] = i;
    }
    std::string res;
    int pos = -1;
    for (auto [k,v] : mp) {
        res += s[v];
        pos = v;
        break;
    }
    res += s.substr(0,pos) + s.substr(pos + 1);
    std::cout << res << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}



CodeForces1805C

原题链接

思路:

题目要求找到任意一条不与抛物线有交点的直线。对于每一条抛物线,我们可以二分找到距离b最近的k。b为抛物线方程y=a * x * x + b * x + c; (二者无交点当且仅当二者方程联立后b * b - 4 * a * c < 0).保证b - k 最小,我们需要找到距离最近的k。则k在b的左右两边.详细见代码

#include 

using i64 = long long;
using PII = std::pair<int,int>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n, m;
    std::cin >> n >> m;

    std::vector<int> x(n);
    std::vector<std::array<int,3>> p(m);

    for (int i = 0; i < n; i ++) {
        std::cin >> x[i];
    }

    for (int i = 0; i < m; i ++) {
        int a, b, c;
        std::cin >> a >> b >> c;
        p[i] = {a,b,c};
    }

    std::sort(x.begin(), x.end());

    for (int i = 0; i < m; i ++) {
        auto [a,b,c] = p[i];

        int k = std::lower_bound(x.begin(), x.end(),b) - x.begin();

        if (k >= n) {//特判边界值,如果没有找到比b大的,那我们就要比b小一点的
            k --;
        }
        if ((b - x[k]) * (b - x[k]) < 4 * a * c) {
            yes
            std::cout << x[k] << "\n";
            continue;
        }
        if ((b - x[std::max(0ll,k - 1)]) * (b - x[(std::max(0ll,k - 1))]) < 4 * a * c) {
            yes
            std::cout << x[std::max(0ll,k - 1)] << "\n";
            continue;
        }
        no
    }
    std::cout << "\n";
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}



CodeForces1805D

原题链接

思路:

求每个点为根的树高。树形DP

#include 

using i64 = long long;
using PII = std::pair<int,int>;
#define int i64
#define yes std::cout << "YES\n";
#define no std::cout << "NO\n";

void solve() {
    int n;
    std::cin >> n;

    std::vector<std::vector<int>> adj(n + 1);
    for (int i = 1; i < n; i ++) {
        int u, v;
        std::cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    std::vector<int> dp(n + 1);
    auto dfs = [&](auto&& dfs,int u,int fa) -> void {
        for (auto v : adj[u]) {
            if (v == fa) continue;
            dfs(dfs,v,u);
            dp[u] = std::max(dp[u],dp[v] + 1);
        }
    };

    std::vector<int> c(n + 10);
    auto dfs2 = [&](auto&& dfs2,int u, int fa) -> void {
        c[dp[u] + 1]++;
        int N = adj[u].size();
        std::vector<int> pre(N + 10), suf(N + 10);
        for (int i = 0; i < N; i++)
            pre[i + 1] = std::max(pre[i], dp[adj[u][i]] + 1);
        for (int i = N - 1; i >= 0; i--)
            suf[i + 1] = std::max(suf[i + 2], dp[adj[u][i]] + 1);
        for (int j = 0; j < N; j++)
        {
            int v = adj[u][j];
            if (v == fa) continue;
            dp[u] = std::max(pre[j], suf[j + 2]);
            dp[v] = std::max(dp[v], dp[u] + 1);
            dfs2(dfs2,v, u);
        }
    };


    dfs(dfs,1,-1);

    dfs2(dfs2,1,-1);

    c[1] = 1;
    for (int i = 2; i <= n; i++)
        c[i] = std::min(n, c[i] + c[i - 1]);
    for (int i = 1; i <= n; i++)
        std::cout << c[i] << " \n"[i == n];
}       

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    
    int T = 1;
    
    // std::cin >> T;

    while (T -- ) {
        solve();
    }
    return 0;
}

CodeForces1805E

原题链接

树链刨分,DSU on tree

你可能感兴趣的:(算法,CodeForces,c++,算法,开发语言)