Codeforces Round 1000 (Div. 2)
A. Minimal Coprime
题意:互素区间是指
根据数论的基础知识,
点击查看代码
void solve() {
int l, r;
std::cin >> l >> r;
int ans = r - l;
if (l == 1) {
ans = std::max(ans, 1);
}
std::cout << ans << "\n";
}
B. Subsequence Update
题意:给你一个数组,你可以翻转一个子序列,求一次操作后
赛时把子序列看成子数组了。。。
左边的最小的
点击查看代码
void solve() {
int n, l, r;
std::cin >> n >> l >> r;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
auto b = a;
std::sort(a.begin(), a.begin() + r);
i64 sum1 = 0, sum2 = 0;
for (int i = 0; i < r - l + 1; ++ i) {
sum1 += a[i];
}
std::sort(b.begin() + l - 1, b.end());
for (int i = l - 1; i < l - 1 + r - l + 1; ++ i) {
sum2 += b[i];
}
i64 ans = std::min(sum1, sum2);
std::cout << ans << "\n";
}
C. Remove Exactly Two
题意:给你一颗树,你要删掉两个点,然后使得剩下的连通块最大。
设
这题赛时代码写的奇丑。
点击查看代码
struct DSU {
std::vector<int> f, siz;
DSU() {}
DSU(int n) {
init(n);
}
void init(int n) {
f.resize(n);
std::iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int find(int x) {
while (x != f[x]) {
x = f[x] = f[f[x]];
}
return 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];
f[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
void solve() {
int n;
std::cin >> n;
std::vector<std::vector<int> > adj(n);
std::vector<std::pair<int, int> > edges;
std::vector<int> deg(n);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back(v);
adj[v].push_back(u);
++ deg[u]; ++ deg[v];
edges.push_back({u, v});
}
if (n == 2) {
std::cout << 0 << "\n";
return;
}
int max = *std::max_element(deg.begin(), deg.end());
std::vector<int> b;
int x = -1, y = -1, mx = 0;
for (int i = 0; i < n; ++ i) {
if (deg[i] == max) {
b.push_back(i);
}
}
if (b.size() >= 2) {
int mx = 0;
for (auto & u : b) {
for (auto & v : b) {
if (u != v) {
int flag = 0;
for (auto & x : adj[u]) {
if (x == v) {
flag = 1;
break;
}
}
if (max * 2 - flag > mx) {
mx = max * 2 - flag;
x = u, y = v;
}
}
}
if (mx == 2 * max) {
break;
}
}
} else {
x = b[0];
int mx = -1;
for (int i = 0; i < n; ++ i) {
if (i == x) {
continue;
}
int flag = 0;
for (auto & j : adj[i]) {
if (x == j) {
flag = 1;
break;
}
}
if (max + deg[i] - flag > mx) {
mx = max + deg[i] - flag;
y = i;
}
}
}
DSU d(n);
for (auto & [u, v] : edges) {
if (u != x && u != y && v != x && v != y) {
d.merge(u, v);
}
}
int ans = 0;
for (int i = 0; i < n; ++ i) {
if (i != x && i != y && d.find(i) == i) {
++ ans;
}
}
std::cout << ans << "\n";
}
D. Game With Triangles
题意:给你两个数组
显然我们应该学最大最小的,那么每次选
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n), b(m);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
for (int i = 0; i < m; ++ i) {
std::cin >> b[i];
}
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
std::vector<int> A, B;
for (int i = 0; i < n / 2; ++ i) {
A.push_back(a[n - 1 - i]- a[i]);
}
for (int i = 0; i < m / 2; ++ i) {
B.push_back(b[m - 1 - i] - b[i]);
}
std::vector<i64> ans;
int x = 0, y = 0;
i64 sum = 0;
while (1) {
if (x >= A.size() && y >= B.size()) {
break;
}
if (n - (x * 2 + y) >= 2 && m - (x + y * 2) >= 2) {
if (A[x] >= B[y]) {
sum += A[x ++ ];
} else {
sum += B[y ++ ];
}
} else if (n - (x * 2 + y) >= 2 && m - (x + y * 2) >= 1) {
sum += A[x ++ ];
} else if (n - (x * 2 + y) >= 1 && m - (x + y * 2) >= 2) {
sum += B[y ++ ];
} else if (x * 2 + y == n && x - 1 + y * 2 + 4 <= m && y + 2 <= B.size() && x) {
sum -= A[ -- x];
A.pop_back();
sum += B[y ++ ];
sum += B[y ++ ];
} else if (x + y * 2 == m && x * 2 + y - 1 + 4 <= n && x + 2 <= A.size() && y) {
sum -= B[ -- y];
B.pop_back();
sum += A[x ++ ];
sum += A[x ++ ];
} else {
break;
}
ans.push_back(sum);
}
std::cout << ans.size() << "\n";
for (int i = 0; i < ans.size(); ++ i) {
std::cout << ans[i] << " ";
}
std::cout << "\n";
}
E. Triangle Tree
题意:给你一棵树,对于任意两个点
观察三角形的性质,如果已经确定了两条边
设
现在观察这个式子
再看
如何计算
最后看存在祖孙关系的点对贡献了多少个-1,直接减去
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::vector<int> > adj(n);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back(v);
adj[v].push_back(u);
}
i64 ans = 0;
std::vector<int> size(n), d(n + 1), cnt(n + 1), sum(n + 2);
auto dfs = [&](auto self, int u, int fa) -> void {
cnt[d[u]] += 1;
size[u] = 1;
i64 tot = 0;
for (auto & v : adj[u]) {
if (v == fa) {
continue;
}
d[v] = d[u] + 1;
self(self, v, u);
tot += (i64)size[u] * size[v];
size[u] += size[v];
}
ans -= 2ll * d[u] * tot;
ans += size[u] - 1;
};
d[0] = 1;
dfs(dfs, 0, -1);
for (int i = n; i >= 1; -- i) {
sum[i] = cnt[i] + sum[i + 1];
}
for (int i = 1; i <= n; ++ i) {
ans += 2ll * i * ((i64)sum[i + 1] * cnt[i] + (i64)cnt[i] * (cnt[i] - 1) / 2);
}
ans = ans - (i64)n * (n - 1) / 2;
std::cout << ans << "\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话