牛客练习赛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';
}