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\) 的子树大小,则:
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