Codeforces Round 872 (Div. 1 & Div. 2) 题解

这场寄大了。

rating -= 99。

赛前说自己可以上 Candidate Master,只差 29 分,结果,,,,。

https://codeforces.com/contest/1824

https://codeforces.com/contest/1825

2A. LuoTianyi and the Palindrome String

因为给出的 \(s\) 是一个回文串,所以答案只可能是 \(-1\) 或者 \(n - 1\),只需要看一下删掉哪一个即可,然后判定,这些都是平凡的。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
	int x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	return !f ? x : -x;
}
char s[55], t[55];
int n;
signed main () {
	int _ = read ();
	while (_ --) {
		scanf ("%s", s + 1);
		n = strlen (s + 1);
		int ans = -1;
		for (int i = 1;i <= n; ++ i) {
			int tot = 0;
			for (int j = 1;j <= n; ++ j) {
				if (i != j) t[++ tot] = s[j];
			}
			int ok = 1;
			for (int j = 1;j <= n - 1; ++ j) {
				ok &= (t[j] == t[n - 1 - j + 1]);
			}
			if (!ok) ans = n - 1;
		}
		printf ("%d\n", ans);
	}
}
/* PT is thinking here ...... */
/* Hope to be candidate master tonight! */

2B. LuoTianyi and the Table

我们要最大化每个前缀矩形的极差之和,那么在 \(a_{1,1},a_{1,2},a_{2,1}\) 必须放最大的,次大的,最小的,次小的,然后枚举这几种情况然后将极差之和取个 max 就行。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
	int x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	return !f ? x : -x;
}
int n, m, b[10005], a[105][105];
inline int f () {
	int ans = 0;
	ans += a[1][1];
	ans += max (a[1][1], a[1][2]) * (m - 1);
	ans += max (a[1][1], a[2][1]) * (n - 1);
	ans += max ({a[1][1], a[1][2], a[2][1]}) * (n - 1) * (m - 1);
	ans -= a[1][1];
	ans -= min (a[1][1], a[1][2]) * (m - 1);
	ans -= min (a[1][1], a[2][1]) * (n - 1);
	ans -= min ({a[1][1], a[1][2], a[2][1]}) * (n - 1) * (m - 1);
//	if (ans == 12) {
//		printf ("a[1][1] = %lld, a[1][2] = %lld, a[2][1] = %lld\n", a[1][1], a[1][2], a[2][1]);
//	}
	return ans;
}
signed main () {
	int _ = read ();
	while (_ --) {
		n = read (), m = read ();
		int ans = -9e18;
		for (int i = 1;i <= n * m; ++ i) b[i] = read ();
		sort (b + 1, b + 1 + n * m);
		a[1][1] = b[n * m], a[1][2] = b[1], a[2][1] = b[2], ans = max (ans, f ());
		a[1][1] = b[n * m], a[1][2] = b[2], a[2][1] = b[1], ans = max (ans, f ());
		a[1][1] = b[1], a[1][2] = b[n * m], a[2][1] = b[n * m - 1], ans = max (ans, f ());
		a[1][1] = b[1], a[1][2] = b[n * m - 1], a[2][1] = b[n * m], ans = max (ans, f ());
		printf ("%lld\n", ans);
	}
	return 0;
}
/* PT is thinking here ...... */
/* Hope to be candidate master tonight! */

2C/1A. LuoTianyi and the Show

这题费了我 80min & penalty*3 /fn /fn /fn。

思路想了好久才想对,一开始想的是 \(-1\)\(-2\) 一定连在一起用,然后就对着错的思路搞了 1h /fn /fn /fn。

发现我们可以分成三种情况处理:

  • 只用 \(-2\)。从 \(1\)\(m\) 扫一遍,如果有 \(i\) 就直接用,否则花费一个 \(-2\)

  • 只用 \(-1\)。从 \(m\)\(1\) 扫一遍,如果有 \(i\) 就直接用,否则花费一个 \(-1\)

  • \(-1\)\(-2\) 都用。钦定一个至少出现 \(1\) 次的 \(i\)\(1 \sim i\)\(-1\),有空隙就可以插一个 \(-1\) 进去。\(i + 1 \sim m\)\(-2\),有空隙就插一个 \(-2\) 进去。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
	int x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	return !f ? x : -x;
}
int n, m, w[100010], mp[100010], ans, qwq[100010], pre[100010];
inline int solve1 () {
	int tmp = 0, cur = mp[0];
	for (int i = 1;i <= m; ++ i) {
		if (mp[i + 2] > 0) tmp ++;
		else if (cur > 0) cur --, tmp ++;
	}
	return tmp;
}
inline int solve2 () {
	int tmp = 0, cur = mp[1];
	for (int i = m;i >= 1; -- i) {
		if (mp[i + 2] > 0) tmp ++;
		else if (cur > 0) cur --, tmp ++;
	}
	return tmp;
}
inline int solve3 () {
	int res = 0;
	for (int i = 0;i <= m; ++ i) {
		if (!mp[i + 2]) continue;
		int tmp = pre[m];
		int prefix = pre[i], suffix = pre[m] - pre[i];
		prefix = i - prefix;
		suffix = m - i - suffix;
		tmp += min (prefix, mp[1]);
		tmp += min (suffix, mp[0]);
		res = max (res, tmp);
	}
	return res;
}
signed main () {
	int _ = read ();
	while (_ --) {
		n = read (), m = read (), ans = 0;
		for (int i = 1;i <= n; ++ i) w[i] = read (), mp[w[i] + 2] ++;
		for (int i = 1;i <= m; ++ i) qwq[i] = mp[i + 2] > 0 ? 1 : 0;
		pre[0] = 0;
		for (int i = 1;i <= m; ++ i) pre[i] = pre[i - 1] + qwq[i];
//		if (mp[0] + mp[1] == n) ans = max (mp[0], mp[1]);
//		else {
			ans = max (ans, solve1 ());
			ans = max (ans, solve2 ());
			ans = max (ans, solve3 ());
//		}
		for (int i = 1;i <= n; ++ i) mp[w[i] + 2] --;
		printf ("%d\n", ans);
	}
	return 0;
}
/* PT is thinking here ...... */
/* Hope to be candidate master tonight! */

2D1/1B1. LuoTianyi and the Floating Islands (Easy Version)

Conclusion 1. 当 \(k \bmod 2 = 1\) 时,答案为 \(1\)

Conclusion 2. 若一棵树的根节点为 \(1\),设 \(siz_k\) 表示 \(k\) 的子树大小,则:

\[\sum_{i = 1}^{n}\sum_{j = 1}^{i - 1} \texttt{dis}(i, j) = \sum_{k = 2}^{n} siz_k \times (n - siz_k) \]

Conclusion 3. 当 \(k = 2\) 时,只有两点之间的路径上的点时好的。

说的够明白了,只需要按 \(k\) 的值来 solve 即可。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
inline int read () {
	int x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c & 15);
	return !f ? x : -x;
}
const int N = 2e5 + 5, mod = 1e9 + 7;
int n, k, siz[N];
vector < int > G[N];
inline int pow_mod (int a, int b, int p) {
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		b >>= 1, a = a * a % p;
	}
	return res;
}
inline void dfs (int u, int fa) {
	siz[u] = 1;
	for (int v : G[u]) {
		if (v != fa) dfs (v, u), siz[u] += siz[v];
	}
}
signed main () {
	n = read (), k = read ();
	for (int i = 1;i < n; ++ i) {
		int u = read (), v = read ();
		G[u].push_back (v);
		G[v].push_back (u);
	}
	if (k & 1) printf ("1\n");
	else {
		dfs (1, 0);
		int ans = 0;
		for (int i = 2;i <= n; ++ i) ans += siz[i] * (n - siz[i]), ans %= mod;
		int qwq = n * (n - 1) / 2; qwq %= mod;
		ans = ans * pow_mod (qwq, mod - 2, mod) % mod;
		ans ++, ans %= mod;
		printf ("%lld\n", ans);
	}
	return 0;
}
// Always keep it simple and stupid
posted @ 2023-05-08 22:44  CountingGroup  阅读(240)  评论(0编辑  收藏  举报