LGR-204-Div.2

Contest link

质量不错的比赛。

A

比较明显的题,贪心往下做就可以。

#include <bits/stdc++.h>

using i64 = long long;

constexpr int N = 1e5 + 7;

int k;
int a[N];

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> k;
	for (int i = 1; i <= k; i++) {
		std::cin >> a[i];
	}
	if (k == 1 && a[1] == 1) { std::cout << "1\n"; exit(0); }
	std::sort(a + 1, a + k + 1);
	int dep = 1, ans = 1;
	for (int i = 1; i <= k; i++) {
		ans += (a[i] - dep);
		dep = a[i] - 1;
	}
	std::cout << ans << "\n";
	return 0;
}

B

比较明显的题,模拟一下往下做就可以。

#include <bits/stdc++.h>

using i64 = long long;

void solve() {
	int n;
	std::string s;
	std::cin >> n >> s;
	int cnt = 1;
	std::vector<int> a(n + 1);
	if (s[0] == '=')
		cnt = 2;
	else
		a[1] = 1;

	char lst = s[0];
	for (int i = 1; i < n - 1; i++) {
		if (s[i] == '=') {
			a[i + 1] = a[i];
			cnt++;
		}
		else if (s[i] == s[i - 1]) {
			a[i + 1] = a[i] + 1;
			cnt = 1;
		}
		else if (s[i] != lst) {
			a[i + 1] = cnt;
			cnt = 1;
			lst = s[i];
		}
		else if (s[i] == lst) {
			a[i + 1] = a[i] + cnt;
			cnt = 1;
		}
	}
	i64 ans = 0;
	for (int i = 0; i <= n; i++)
		ans += a[i];
	std::cout << ans << "\n";
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

C

观察到 \(m \leq 20\) 肯定不对劲,并且好像没有什么现成的方便的 DS 可以快速维护两序列区间排序并,注意到是一个诈骗题,直觉能够感受到在在不多次操作之后整个序列会趋向有序,这时可以直接考虑 swap() 掉,否则就暴力修改插入,然后发现这样是对的,可以证明最多只需要 \(O(m^2)\) 次操作,似乎是 \(\frac{m(m - 1)}{2}\)

注意到它卡输入。

以后非必要没弄懂就不要乱解地址,你搞不明白,而且你 CSP 2024 已经炸了一次 set*

#include <bits/stdc++.h>

using i64 = long long;

template <typename T> T read() {
	T sum = 0, fl = 1;
	int ch = getchar_unlocked();
	for (; !isdigit(ch); ch = getchar_unlocked()) { if (ch == '-') fl = -1; }
	for (; isdigit(ch); ch = getchar_unlocked()) sum = sum * 10 + ch - '0';
	return sum * fl;
}

template <typename T> void write(T x) {
	if (x < 0) { x = -x; putchar_unlocked('-'); }
	if (x > 9) write(x / 10);
	putchar_unlocked(x % 10 + '0');
}

void solve() {
	int n = read<int>(), m = read<int>(), q = read<int>();
	std::vector<int> G[m + 1];
	std::vector<bool> vis(m + 1);
	for (int x = 1; x <= m; x++) {
		for (int i = 1, p; i <= n; i++) {
			p = read<int>();
			G[x].push_back(p);
		}
	}
	while (q--) {
		int opt = read<int>(), x = read<int>(), y = read<int>();
		if (opt == 2) {
			write<int>(G[x][y - 1]);
			puts("");
		} else {
			if (vis[x] && vis[y]) {
				/*if (*G[x].end() <= *G[y].begin())
					continue;
				if (*G[y].end() <= *G[x].begin()) {
					std::swap(G[x], G[y]);
					continue;
				}*/
				if (G[x][G[x].size() - 1] <= G[y][0])
					continue;
				if (G[y][G[y].size() - 1] <= G[x][0]) {
					std::swap(G[x], G[y]);
					continue;
				}
			}
			std::vector<int> v;
			v.insert(v.end(), G[x].begin(), G[x].end());
			v.insert(v.end(), G[y].begin(), G[y].end());
			std::sort(v.begin(), v.end());
			for (int i = 0; i < n; i++)
				G[x][i] = v[i];
			for (int i = n; i < v.size(); i++)
				G[y][i - n] = v[i];
			vis[x] = vis[y] = 1;
		}
	}
}

int main() {
	// std::ios::sync_with_stdio(false);
	// std::cin.tie(nullptr);

	solve();
	return 0;
}

D

试判断是否存在一个 \(n\)\(0\)\(m\)\(1\)\(01\) 串满足对于任意一个长度 \([2L, 2R]\) 的子串,其 \(n\)\(m\) 的数量不相等

学习了一个新的 trick。

对于 \(01\) 串个数相等的问题,可以考虑将其转到二维平面上走网格,选择一个 \(1\) 表示向下走一格,选择一个 \(0\) 表示向下走一格。

这样子做的话我们就成功转化了题面:从 \((m, n)\)\((0, 0)\) 走,走到 \((0, 0)\),每一次移动都会新产生几个障碍,求是否存在一条路径使其不经过障碍。

这样子看起来就可做了很多。

发现障碍的位置是随着移动的位置而平移的,贪心地贴着障碍边界往下走,如果最后障碍的边界与 \(x\) 轴的交点 \(\gt 0\) 就可行。

通过打表找一下周期,特殊处理 \(x\) 轴附近的点就解决问题了。

corner case 好像小多。

周期的探讨还是看 原的 Solution 比较好,照搬过来没什么意思。

好题。

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

void solve() {
	u64 l, r, m, n;
	std::cin >> l >> r >> m >> n;
	if (!n || !m) {
		std::cout << "Yes\n";
		return;
	}
	if (l == 1) {
		std::cout << "No\n";
		return;
	}

	if (n > m) {
		std::swap(n, m);
	}
	u64 a = (n - 1) / (l - 1);
	u64 b = n - a * (l - 1);
	u64 c = a * (l + 1) + std::min(b - 1, a * (r - l));
	if (c <= m)
		std::cout << "Yes\n";
	else
		std::cout << "No\n";
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

posted @ 2024-11-06 19:17  revkiru  阅读(4)  评论(0编辑  收藏  举报