牛客练习赛127

A、小红的最大价值

无聊打一下

代码实现

#include <bits/stdc++.h>

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    #define int long long
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
    }
    int ans = 0;
    std::sort(a.rbegin(), a.rend());
    for (int i = 1; i < n; ++i) {
        if (a[0] - a[i] > k) {
            ans = std::max(ans, std::max(a[0], a[i]));
        } else {
            ans = std::max(ans, std::min(a[0], a[i]));
        }
    }
    std::cout << ans << '\n';
}

B、小红的约数

代码实现

#include <bits/stdc++.h>

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

template <class T>
constexpr T power(T a, long long b) {
    T res = 1;
    for (; b; b /= 2, a *= a)
        if (b % 2) res *= a;
    return res;
}
template <int P>
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(long long x) : x{norm(x % P)} {}
    constexpr int norm(int x) const {
        if (x < 0) x += P;
        if (x >= P) x -= P;
        return x;
    }
    constexpr int val() const { return x; }
    explicit constexpr operator int() const { return x; }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(P - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    constexpr MInt &operator*=(MInt rhs) {
        x = 1ll * x * rhs.x % P;
        return *this;
    }
    constexpr MInt &operator+=(MInt rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &operator-=(MInt rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &operator/=(MInt rhs) { return *this *= rhs.inv(); }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        long long v;
        is >> v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) { return os << a.val(); }
    friend constexpr bool operator==(MInt lhs, MInt rhs) { return lhs.val() == rhs.val(); }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) { return lhs.val() != rhs.val(); }
};

template <int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();

// constexpr int P = 998244353;
constexpr int P = 1e9 + 7;
using Z = MInt<P>;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int w, d;
    std::cin >> w >> d;
    std::vector<std::pair<Z, int>> fac(w);
    for (auto &[p, a] : fac) {
        std::cin >> p >> a;
        p = power(p, d);
    }
    Z ans = 0;
    for (int i = 0; i < (int)size(fac); ++i) {
        auto [p, a] = fac[i];
        Z mul = a;
        if (p != 1) {
            mul = p * (power(p, a) - 1) / (p - 1);
        }
        debug(mul);
        ans += ans * mul + mul;
    }
    std::cout << ans + 1 << '\n';
}

C、小红的图上划分

代码实现

#include <bits/stdc++.h>

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

struct DSU {
    std::vector<int> p, siz;
    DSU(int n) : p(n), siz(n, 1) { std::iota(p.begin(), p.end(), 0); }
    int leader(int x) {
        while (x != p[x]) x = p[x] = p[p[x]];
        return x;
    }
    bool same(int x, int y) { return leader(x) == leader(y); }
    bool merge(int x, int y) {
        x = leader(x), y = leader(y);
        if (x == y) return false;
        siz[x] += siz[y], p[y] = x;
        return true;
    }
    int size(int x) { return siz[leader(x)]; }
};
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, m, q;
    std::cin >> n >> m >> q;
    std::vector<std::array<int, 3>> edges(m);
    for (auto &[w, u, v] : edges) {
        std::cin >> u >> v >> w;
        u--, v--;
    }
    std::sort(edges.rbegin(), edges.rend());
    DSU dsu(n);
    int block = n;
    std::vector<int> ans(n, -2e9);
    for (auto &[w, u, v] : edges) {
        if (dsu.merge(u, v)) {
            block--;
            ans[block] = w;
        }
    }
    while (q--) {
        int L, R;
        std::cin >> L >> R;
        if (ans[R] == -2e9) {
            std::cout << "NO ANSWER" << '\n';
        } else {
            std::cout << ans[R] << '\n';
        }
    }
}

D、小红的白点距离

分析

发现题目的本质就是去除k个点后问树的直径最小是多少,因此直接枚举每个节点为根节点root时,保留距离root最近的\(n-k\)个点,对这些点求一遍直径,取最小值即可。

代码实现

#include <bits/stdc++.h>

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, k;
    std::cin >> n >> k;
    std::vector<std::vector<int>> g(n);
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        std::cin >> u >> v;
        u--, v--;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
    }
    int ans = 1e9;
    for (int root = 0; root < n; ++root) {
        std::vector<int> dep(n, -1), q;
        std::vector<bool> vis(n);
        q.emplace_back(root), dep[root] = 0;
        int c = root;
        for (int i = 0; i < n - k; ++i) {
            auto u = q[i];
            vis[u] = true;
            if (dep[c] < dep[u]) {
                c = u;
            }
            for (auto v : g[u]) if (dep[v] == -1) {
                dep[v] = dep[u] + 1;
                q.emplace_back(v);
            }
        }
        auto dfs = [&](auto &&self, int u, int fa)->void {
            for (auto v : g[u]) if (v != fa && vis[v]) {  
                dep[v] = dep[u] + 1;
                if (dep[c] < dep[v]) {
                    c = v;
                }
                self(self, v, u);
            }
        };
        debug(root, c, dep);
        dep[c] = 0, dfs(dfs, c, -1);
        debug(root, c, dep);
        ans = std::min(ans, dep[c]);
    }
    std::cout << ans << '\n';
}
posted @ 2024-07-06 17:30  sleeeeeping  阅读(23)  评论(0编辑  收藏  举报