← 全部文章

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) 题解

本文目录(6 节)
  1. Math Problem
  2. Box
  3. Messy
  4. Optimal Subsequences
  5. Arson In Berland Forest
  6. Wrong Answer on test 233

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3)

Math Problem

贪心。

inline void solve() {
	int l = 1e9 + 1, r = 0, n;
	rd(n);
	for (int i = 1; i <= n; i++) {
		int x, y;
		rd(x), rd(y);
		r = max(r, x);
		l = min(l, y);
	}
	print(max(r - l, 0));
}

int main() {
	int T;
	rd(T);
	while (T--) solve();
	return 0;
}

Box

贪心。

const int N = 1e5 + 7;
int n, a[N], b[N];

inline void solve() {
	rd(n);
	set< int > s;
	for (int i = 1; i <= n; i++) {
		rd(a[i]), s.insert(i);
	}
	for (int i = 1; i <= n; i++) {
		si it = s.upper_bound(a[i]);
		if (it != s.begin()) b[i] = *--it, s.erase(it);
		else return print(-1), void();
	}
	for (int i = 1; i <= n; i++) print(b[i], " \n"[i==n]);
}

int main() {
	int T;
	rd(T);
	while (T--) solve();
	return 0;
}

Messy

构造。

const int N = 1e5 + 7;
int n, k;
char s[N], c[2] = {')', '('};
vector< pi > ans;

inline void solve() {
	ans.clear();
	rd(n), rd(k), rds(s, n);
	for (int i = 1; i <= n; i++)
		if (s[i] != c[i&1]) {
			int t = i;
			for (int j = i + 1; j <= n; j++)
				if (s[j] == c[i&1]) {
					t = j;
					break;
				}
			ans.pb(mp(i, t));
			reverse(s + i, s + t + 1);
		}
	if (2 * k != n) ans.pb(mp(2 * k, n - 1));
	print(ans.size());
	for (ui i = 0; i < ans.size(); i++)
		print(ans[i].fi, ' '), print(ans[i].se);
}

int main() {
	int T;
	rd(T);
	while (T--) solve();
	return 0;
}

Optimal Subsequences

二分 + 树状数组,O(nlog⁡2n)\mathcal O(n \log^2 n)。

const int N = 2e5 + 7;
int n, m, a[N], c[N], ans[N];
pq< pi > q;
pair< pi, int > p[N];

inline void add(int x) {
	while (x <= n) c[x]++, x += x & -x;
}

inline int ask(int x) {
	int k = 0;
	while (x) k += c[x], x -= x & -x;
	return k;
}

inline int qry(int x) {
	int l = 1, r = n;
	while (l < r) {
		int mid = (l + r) >> 1;
		if (ask(mid) < x) l = mid + 1;
		else r = mid;
	}
	return a[l];
}

int main() {
	rd(n);
	for (int i = 1; i <= n; i++) {
		rd(a[i]);
		q.push(mp(a[i], -i));
	}
	rd(m);
	for (int i = 1, x, y; i <= m; i++) {
		rd(x), rd(y), p[i] = mp(mp(x, y), i);
	}
	sort(p + 1, p + m + 1);
	int t = 0;
	for (int i = 1; i <= m; i++) {
		while (t < p[i].fi.fi) {
			int x = -q.top().se;
			q.pop();
			add(x);
			++t;
		}
		ans[p[i].se] = qry(p[i].fi.se);
	}
	for (int i = 1; i <= m; i++) print(ans[i]);
	return 0;
}

Arson In Berland Forest

(假的)贪心。

const int N = 1e6 + 7;
int n, m, p[N];
string s[N];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 0; i < n; i++) cin >> s[i], s[i].pb('.');
	for (int i = 0; i < m; i++) s[n].pb('.');
	int ans = 1e9;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= m; j++) {
			p[j] = s[i][j] == 'X' ? j ? p[j-1] + 1 : 1 : 0;
			if (s[i][j] == '.' && j && s[i][j-1] == 'X') ans = min(ans, p[j-1]);
		}
	for (int i = 0; i < m; i++)
		for (int j = 0; j <= n; j++) {
			p[j] = s[j][i] == 'X' ? j ? p[j-1] + 1 : 1 : 0;
			if (s[j][i] == '.' && j && s[j-1][i] == 'X') ans = min(ans, p[j-1]);
		}
	ans = (ans - 1) / 2;
	cout << ans << endl;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= m; j++) {
			p[j] = s[i][j] == 'X' ? j ? p[j-1] + 1 : 1 : 0;
			if (p[j] <= ans) s[i][j] = '.';
		}
	for (int i = 0; i < n; i++)
		for (int j = m; j >= 0; j--) {
			p[j] = s[i][j] == 'X' ? j < m ? p[j+1] + 1 : 1 : 0;
			if (p[j] <= ans) s[i][j] = '.';
		}
	for (int i = 0; i < m; i++)
		for (int j = 0; j <= n; j++) {
			p[j] = s[j][i] == 'X' ? j ? p[j-1] + 1 : 1 : 0;
			if (p[j] <= ans) s[j][i] = '.';
		}
	for (int i = 0; i < m; i++)
		for (int j = n; j >= 0; j--) {
			p[j] = s[j][i] == 'X' ? j < n ? p[j+1] + 1 : 1 : 0;
			if (p[j] <= ans) s[j][i] = '.';
		}
	for (int i = 0; i < n; i++) s[i].pop_back(), cout << s[i] << endl;
	return 0;
}

Wrong Answer on test 233

首先如果相邻两个正确选项一样,那么这个位置选什么都不会产生影响,因此直接将答案 ×k\times k。

如果不一样,那么对于每一个位置的生成函数为 F(x)=x−1+(k−2)+xF(x) = x^{-1} + (k - 2) + x。

设相邻两个正确选项不一样的位置有 cc 个,那么答案就是 Fc(x)F^c(x) 的正项系数和 ×kn−c\times k^{n-c}。

枚举 (k−2)(k-2) 项的次数,设剩下的次数为 ii,此时正项系数和为 (ci)∑2j>i(ij)=(ci)×2i−[2∣i](ii2)2\binom{c}{i}\sum_{2j > i} \binom{i}{j} = \binom{c}{i} \times \frac{2^i - [2|i]\binom{i}{\frac{i}{2}}}2。

忽略模运算后时间复杂度为 O(n)\mathcal O(n)。

const int N = 2e5 + 7;
int n, k, a[N], c;
modint p[N], ans;

int main() {
	rd(n), rd(k);
	for (int i = 1; i <= n; i++) rd(a[i]);
	c = a[1] != a[n];
	for (int i = 1; i < n; i++) c += a[i] != a[i+1];
	p[0] = 1;
	for (int i = 1; i <= c; i++) p[i] = p[i-1] * i;
	for (int i = 0; i <= c; i++) ans += (p[c] / p[i] / p[c-i]) * (((modint)2 ^ i) - ((i & 1) ? 0 : p[i] / p[i>>1] / p[i>>1])) * ((modint)(k - 2) ^ (c - i)) / 2;
	ans *= (modint)k ^ (n - c);
	print(ans);
	return 0;
}

标签:二分、构造、树状数组、生成函数、组合计数、贪心

评论

    填写昵称即可留言。评论经站主审核后公开,请勿提交私人信息。

    正在连接评论服务…