Loading

Codeforces Round 1000 (Div. 2)



A - Minimal Coprime

题意

当区间\([l',r']\)\(l'\)\(r'\)互质,称这个区间为互质区间;当互质区间\([l',r']\)中没有其他元素与\(l'\)\(r'\)互质,则称这个区间为最小互质区间。现在给定区间\([l,r]\),求\([l,r]\)中的最小互质区间个数

思路

CF签到题直接猜\(l=r\)时特殊处理,其他情况\(x\)\(x+1\)一定是互质的,数量就是\(r-l\)

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 2e5 + 5;

void solve()
{
	int l, r;
	cin >> l >> r;
	if (l == r)
	{
		cout << (l == 1 ? 1 : 0) << endl;
		return;
	}
	cout << r - l << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}

B - Subsequence Update

题意

给定正整数序列\(a\),选择其任意子序列颠倒,使得区间\([l,r]\)的元素和最小

思路

显然是选择区间左边或区间右边的数交换最优,如果左右都选了并没有进行区间内的交换。那就只用小换大,然后输出最小值。

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 2e5 + 5;

void solve()
{
	int n, l, r;
	cin >> n >> l >> r;
	vector<int> L(l - 1), M(r - l + 1), R(n - r);
	for (int i = 0; i < L.size(); i++)
	{
		cin >> L[i];
	}
	for (int i = 0; i < M.size(); i++)
	{
		cin >> M[i];
	}
	for (int i = 0; i < R.size(); i++)
	{
		cin >> R[i];
	}
	sort(L.begin(), L.end());
	sort(M.begin(), M.end(), greater<int>());
	sort(R.begin(), R.end());
	int x = 0, y = 0, xx = L.size(), yy = R.size();
	for (int i = 0; i < min(L.size(), M.size()); i++)
	{
		if (L[i] <= M[i])
		{
			x += L[i];
		}
		else
		{
			xx = i;
			break;
		}
	}
	for (int i = min(xx, (int)M.size()); i < M.size(); i++)
	{
		x += M[i];
	}
	for (int i = 0; i < min(R.size(), M.size()); i++)
	{
		if (R[i] <= M[i])
		{
			y += R[i];
		}
		else
		{
			yy = i;
			break;
		}
	}
	for (int i = min(yy, (int)M.size()); i < M.size(); i++)
	{
		y += M[i];
	}
	cout << min(x, y) << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}


C - Remove Exactly Two

题意

给定一棵树,执行两次操作:删除顶点\(v\)及与其关联的边,求得到的森林中树的数量最大值。

思路

最后的答案取决于删除的两个点的度数及其是否相邻,相邻\(ans = deg[u] + deg[v] - 2\),不相邻\(ans = deg[u] + deg[v] - 1\)\(DFS\)得出所有答案会\(T\),所以维护一个\(multiset\)储存各个顶点的入度,在枚举不相邻的点时,删除相邻顶点的入度,直接看度数最大的点即可。
注意:\(s.erase(x)\)会删除\(multiset\)中所有值为\(x\)的元素

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 5e5 + 5;

void solve()
{
	int n, ans = 0;
	cin >> n;
	vector<int> deg(n + 1);
	vector<vector<int>> g(n + 1);
	multiset<int> s;
	for (int i = 1; i < n; i++)
	{
		int u, v;
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
		deg[u]++;
		deg[v]++;
	}
	for (int i = 1; i <= n; i++)
	{
		s.insert(deg[i]);
	}
	for (int u = 1; u <= n; u++)
	{
		for (auto& v : g[u])
		{
			ans = max(ans, deg[u] + deg[v] - 2);
			s.erase(s.find(deg[v]));
		}
		s.erase(s.find(deg[u]));
		if (s.size())
		{
			ans = max(ans, *s.rbegin() + deg[u] - 1);
		}
		for (auto& v : g[u])
		{
			s.insert(deg[v]);
		}
		s.insert(deg[u]);
	}
	cout << ans << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	int T = 1;
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}


比赛链接 https://mirror.codeforces.com/contest/2063

posted @ 2025-02-03 20:45  _SeiI  阅读(148)  评论(0)    收藏  举报