目录
D-修改后的和_牛客小白月赛74 (nowcoder.com)
E-幼稚园的树2_牛客小白月赛74 (nowcoder.com)
F-最便宜的构建_牛客小白月赛74 (nowcoder.com)
前言:
主要是存一下代码,因为时间紧,所以没仔细解析。
正文:
D-修改后的和_牛客小白月赛74 (nowcoder.com)
思路:
vec存放贡献大于0的,按贡献进行排序,取能取的前个即可
代码:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
void solve() {
int n, m;
cin >> n >> m;
vector<int> vec; // vec:存放贡献大于0的下标
vector<i64> a(n), can(n); // can:存放贡献
for (int i = 0; i < n; i++) {
cin >> a[i];
can[i] = max(0LL, 1LL * a[i] * (n - i));
if (can[i] > 0) {
vec.push_back(i);
}
}
sort(vec.begin(), vec.end(), [&](int x, int y){
return can[x] > can[y];
});
i64 ans = accumulate(a.begin(), a.end(), 0LL); // 注意使用这个函数long long时候需要0LL !!!
for (int i = 0; i < min(int(vec.size()), m); i++) {
ans -= can[vec[i]];
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
E-幼稚园的树2_牛客小白月赛74 (nowcoder.com)
思路:
分情况搞一下就行,当时没过是因为没注意到即使整除也只能到下一天这个事
代码:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int N = 2e5 + 10;
i64 a[N], h[N], ans[N];
i64 fir, sec;
int n, m, k, b;
void solve() {
cin >> n >> m >> k >> b;
for (int i = 1; i <= n; i++) {
cin >> h[i];
}
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (h[i] + (m - 1) * a[i] <= k) { // 永远达不到k
ans[i] = h[i] + (m - 1) * a[i];
} else { // 达到k后反复清除
i64 fir = (k - h[i]) / a[i] + 1; // 这里不是 + a[i] -1上取整这种做法,而是直接+1,因为即使整除也只能在下一天
i64 sec = (k - b) / a[i] + 1;
int lev = (m - 1) - fir;
lev %= sec;
ans[i] = b + lev * a[i];
}
}
for (int i = 1; i <= n; i++) {
cout << ans[i] << " \n"[i == n];
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
F-最便宜的构建_牛客小白月赛74 (nowcoder.com)
思路:
二分答案,二分边权最大值最小,使用并查集检验点集的连通性即可
代码:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
struct DSU {
std::vector<int> p, siz;
DSU(int n) : p(n + 1), siz(n + 1, 1) {
std::iota(p.begin(), p.end(), 0);
}
int find(int x) {
return p[x] == x ? x : p[x] = find(p[x]);
}
bool same(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return false;
}
siz[x] += siz[y];
p[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
struct edge {
int u, v, w;
};
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<edge> vec(m);
for (int i = 0; i < m; i++) {
cin >> vec[i].u >> vec[i].v >> vec[i].w;
}
sort(vec.begin(), vec.end(), [&](const edge &A, const edge &B){
return A.w < B.w;
});
int k;
cin >> k;
vector<int> vertex[k];
for (int i = 0; i < k; i++) {
int s;
cin >> s;
vertex[i].resize(s);
for (int j = 0; j < s; j++) {
cin >> vertex[i][j];
}
}
auto check = [&](int x) {
DSU dsu(n);
for (int i = 0; i < m; i++) {
if (vec[i].w > x) {
break;
}
dsu.merge(vec[i].u, vec[i].v);
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < vertex[i].size(); j++) {
if (dsu.find(vertex[i][j]) != dsu.find(vertex[i][0])) {
return false;
}
}
}
return true;
};
int l = 1, r = 1E9;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
cout << l << "\n";
return 0;
}