Codeforces Round 1014 (Div. 2)

A. Kamilka and the Sheep

Kamilka 有 \(n\) 只羊,第 \(i\) 只羊的美丽值为 \(a_i\)(所有 \(a_i\) 互不相同)。早晨喂食时,Kamilka 可以选择一个非负整数 \(d\),给每只羊增加 \(d\) 的美丽值。傍晚,她必须选择恰好两只羊,其经过喂食后的美丽值分别为 \(x\)\(y\)。Kamilka 的快乐值为 \(\gcd(x, y)\),求最大可能的快乐值。
\(n \leq 100, a_i \leq 10^9\)

对于两个正整数 \(i,j(i<j)\)\(\gcd (i,j) \leq j - i\),并且一定能找到一个 \(d\) 使得 \(i + d = k(j - i)\),此时 \(\gcd (i + d, j + d) = j - i\),答案为数组最大值减去最小值。

代码
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const int N = 2000086, MOD = 998244353, INF = 0x3f3f3f3f;
ll res;
int n, m, cnt, w[N];

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 1; i < n + 1; i++) scanf("%d", w + i);
        sort(w + 1, w + n + 1);
        printf("%d\n", w[n] - w[1]);
    }
    return 0;
}

B. Lady Bug

Dasha Purova 一踏入法国国境,就被恶棍 Markaron 绑架,并关进了他那座大城堡下的监狱。幸运的是,听闻 Dasha 消息的美丽 Lady Bug 立即赶往 Markaron 城堡去救她。然而,为了进入城堡,她需要破解一个复杂的密码。该密码由两个长度为 \(n\) 的二进制串 \(a\)\(b\) 组成。Lady Bug 可以进行任意次数的操作,每次操作中她可以选择任一索引 \(2 \le i \le n\),并执行下列两种操作之一:

  • 交换 \(a_i\)\(b_{i-1}\) 的值,即执行 \(swap(a_i,\, b_{i-1})\)
  • 交换 \(b_i\)\(a_{i-1}\) 的值,即执行 \(swap(b_i,\, a_{i-1})\)

当 Lady Bug 能够使得字符串 \(a\) 全部变为 \(0\) 时,密码即被破解。请判断她是否有可能成功救出不幸的 Dasha。
\(n \leq 2 \times 10^5\)

交换操作实际使得 \(a\) 中奇数位置和 \(b\) 中偶数位置以及 \(a\) 中的偶数位置和 \(b\) 中的奇数位置可以任意交换,判断能否将 \(a\) 中所有 \(1\) 交换到 \(b\) 即可。

代码
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const int N = 2000086, MOD = 998244353, INF = 0x3f3f3f3f;
ll res;
int n, m, cnt, w[N];


char a[N], b[N];

void solve() {
    int c1 = 0, c2 = 0;
    for (int i = 1; i < n + 1; i++) {
        if (a[i] == '1') {
            c1 += i & 1;
            c2 += i & 1 ^ 1;
        }
        if (b[i] == '1') {
            c1 += i & 1 ^ 1;
            c2 += i & 1;
        }
    }
    puts(c1 > n / 2 || c2 > (n + 1) / 2 ? "NO" : "YES");
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        scanf("%s%s", a + 1, b + 1);
        solve();
    }
    return 0;
}

C. Asuna and the Mosquitoes

Asuna 的 \(n\) 位崇拜者在她生日时各送了她一座塔,第 \(i\) 位崇拜者送的塔高为 \(a_i\)。Asuna 认为这些礼物的美丽值为 \(\max(a_1, a_2, \dots, a_n)\)。她可以进行任意次数(也可以为 \(0\))如下操作:

  • 选择任意两个下标 \(1 \le i \ne j \le n\),如果 \(a_i + a_j\) 是奇数,且 \(a_i > 0\)

那么将 \(a_i\)\(1\),同时将 \(a_j\)\(1\)。显然,在操作过程中塔的高度始终保持非负。请帮 Asuna 计算,在进行任意次数操作后,礼物可能达到的最大美丽值是多少。
\(n \leq 2 \times 10^5, a_i \leq 10^9\)

如果数组只有奇数或者只有偶数,显然一次操作也无法执行。

对于既有奇数也有偶数的情况,首先操作是不会改变数组中奇数的个数的,如果数组所有值的总和为 \(sum\),奇数个数为 \(cnt\),那么操作后的最大值一定小于等于 \(sum - cnt + 1\)。对于一个奇数 \(a_i\) 和一个偶数 \(a_j\),可以通过 \(a_j\) 次操作使把偶数全部加到奇数上,或者通过 \(a_i - 1\) 操作把奇数变成 \(1\),剩余的加到偶数上,因此我们可以先把所有奇数加到偶数上,再把所有偶数加到一个奇数上,此时可以取到最大值 \(sum - cnt + 1\)

代码
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const int N = 2000086, MOD = 998244353, INF = 0x3f3f3f3f;
ll res;
int n, m, cnt, w[N];

void solve() {
    sort(w + 1, w + n + 1);
    bool flag1 = 0, flag2 = 0;
    for (int i = 1; i < n + 1; i++) flag1 |= w[i] & 1, flag2 |= w[i] & 1 ^ 1;
    if (!flag1 || !flag2) {
        printf("%d\n", w[n]);
        return;
    }
    res = 0;
    for (int i = 1; i < n + 1; i++) {
        if (w[i] & 1) res += w[i] - 1;
        else res += w[i];
    }
    res++;
    printf("%lld\n", res);
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        for (int i = 1; i < n + 1; i++) scanf("%d", w + i);
        solve();
    }
    return 0;
}

D. Mishkin Energizer

Edmond 正在为与老友 Fernan 的决斗做准备,他研发了一款名为 “Mishkin Energizer” 的能量饮料。饮料由一个长度为 \(n\) 的字符串 \(s\) 构成,字符串仅包含字符 L、I 和 T,分别代表饮料中三种不同成分的含量。如果饮料中三种成分的数量相等,则称该饮料为平衡饮料。为了增强气场并确保决斗胜利,Edmond 必须通过以下操作使初始字符串变为平衡状态:

  • 选择一个索引 \(i\),满足 \(s_i \ne s_{i+1}\)(且 \(i+1\) 不超过字符串当前长度
  • \(s_i\)\(s_{i+1}\) 之间插入一个字符 \(x\)(字符 \(x\) 可以是 L、I 或 T),要求 \(x \ne s_i\)\(x \ne s_{i+1}\)

请帮助 Edmond 在不超过 \(2n\) 次操作内使饮料平衡。如果存在多种方案,输出任一方案;如果不可能实现,则报告这一情况。
\(n \leq 100\)

如果只有一种字符,显然无法平衡。否则每次选择数量最小且有位置可以插入的字符进行操作即可。

代码
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const int N = 2000086, MOD = 998244353, INF = 0x3f3f3f3f;
ll res;
int n, m, cnt, w[N];


char s[N];
void solve() {
    int c1 = 0, c2 = 0, c3 = 0;
    for (int i = 1; i < n + 1; i++) c1 += s[i] == 'L', c2 += s[i] == 'I', c3 += s[i] == 'T';
    if (c1 == n || c2 == n || c3 == n) {
        puts("-1");
        return;
    }

    vector<char> v;
    vector<int> ans;
    for (int i = 1; i < n + 1; i++) v.push_back(s[i]);
    int c = max({c1, c2, c3});
    while (c1 < c || c2 < c || c3 < c) {
        if (ans.size() > 2 * n) break;
        bool flag = 0;
        if (c1 < c) {
            for (int i = 0; i < v.size() - 1; i++) {
                if (v[i] != v[i + 1] && v[i] != 'L' && v[i + 1] != 'L') {
                    v.insert(v.begin() + i + 1, 'L');
                    ans.push_back(i + 1);
                    c1++;
                    flag = 1;
                    break;
                }
            }
        }
        if (c2 < c) {
            for (int i = 0; i < v.size() - 1; i++) {
                if (v[i] != v[i + 1] && v[i] != 'I' && v[i + 1] != 'I') {
                    v.insert(v.begin() + i + 1, 'I');
                    ans.push_back(i + 1);
                    c2++;
                    flag = 1;
                    break;
                }
            }
        }
        if (c3 < c) {
            for (int i = 0; i < v.size() - 1; i++) {
                if (v[i] != v[i + 1] && v[i] != 'T' && v[i + 1] != 'T') {
                    v.insert(v.begin() + i + 1, 'T');
                    ans.push_back(i + 1);
                    c3++;
                    flag = 1;
                    break;
                }
            }
        }
        if (!flag) {
            if (c1 <= max(c2, c3)) {
                for (int i = 0; i < v.size() - 1; i++) {
                    if (v[i] != v[i + 1] && v[i] != 'L' && v[i + 1] != 'L') {
                        v.insert(v.begin() + i + 1, 'L');
                        ans.push_back(i + 1);
                        c1++;
                        goto NE;
                    }
                }
            }
            if (c2 <= max(c1, c3)) {
                for (int i = 0; i < v.size() - 1; i++) {
                    if (v[i] != v[i + 1] && v[i] != 'I' && v[i + 1] != 'I') {
                        v.insert(v.begin() + i + 1, 'I');
                        ans.push_back(i + 1);
                        c2++;
                        goto NE;
                    }
                }
            }
            if (c3 <= max(c1, c2)) {
                for (int i = 0; i < v.size() - 1; i++) {
                    if (v[i] != v[i + 1] && v[i] != 'T' && v[i + 1] != 'T') {
                        v.insert(v.begin() + i + 1, 'T');
                        ans.push_back(i + 1);
                        c3++;
                        goto NE;
                    }
                }
            }
            NE:;
            c = max({c1, c2, c3});
        }
    }
    if (ans.size() > 2 * n) {
        puts("-1");
        return;
    }

    printf("%d\n", ans.size());
    for (auto u : ans) printf("%d\n", u);
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        scanf("%s", s + 1);
        solve();
    }
    return 0;
}

E. She knows...

D. Pippy 正在为他家举办的“黑白派对”做准备。他只需要重新粉刷地下室的地板,该地板可以表示为一个大小为 \(n \times m\) 的棋盘。在上次派对之后,除了一些 \(k\) 个细胞 \((x_1, y_1), (x_2, y_2), \dots, (x_k, y_k)\) 外,整块棋盘都被漆成了绿色,每个给定的细胞已经被漆成黑色或白色。为了即将到来的派对,D. Pippy 想将剩下的绿色细胞重新涂成黑色或白色。同时,他希望重新粉刷后,棋盘上相邻颜色不同的细胞对数为偶数。
形式化地,设

\[A = \{ ((i_1,j_1),(i_2,j_2)) \mid 1 \le i_1,i_2 \le n,\ 1 \le j_1,j_2 \le m,\ i_1+j_1 < i_2+j_2,\ |i_1-i_2|+|j_1-j_2| = 1,\ \text{color}(i_1,j_1) \ne \text{color}(i_2,j_2) \}, \]

其中 \(\text{color}(x,y)\) 表示细胞 \((x,y)\) 的颜色,则要求 \(|A|\) 为偶数。
求有多少种方法可以重新粉刷地板使得上述条件满足。由于答案可能很大,请输出答案对 \(10^9+7\) 取模后的结果。
\(n,m \leq 10^9,k \leq 2 \times 10^5\)

两个格子的颜色不同实际上就是对两个格子的颜色进行异或操作,而在模 \(2\) 的意义下,异或是等价于加的,因此每个格子对 \(|A|\) 的贡献为这个格子的边数乘以格子颜色。一个格子如果有偶数条边,翻转这个格子不会影响 \(|A|\) 的奇偶性,因此我们只需要考虑边框上除去四个角的那些格子。统计边框未被染色的格子数量为 \(u\),非边框未被染色的格子数量为 \(t\),边框已染色格子的颜色和模 \(2\)\(x\),如果 \(u\)\(0\),若 \(x\)\(1\),此时方案数为 \(0\),否则方案数为 \(2 ^ t\),如果 \(u\) 不为 \(0\),方案数为 \(2^{t+u-1}\)

代码
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
const int N = 2000086, MOD = 1e9 + 7, INF = 0x3f3f3f3f;
ll res;
int n, m, cnt, w[N];

inline ll qmi(ll a, ll b, ll c) { ll res = 1; while (b) { if (b & 1) res = res * a % c; a = a * a % c; b >>= 1; } return res; }

int k;
void solve() {
    ll u = 0, v = 0;
    int k;
    cin >> n >> m >> k;
    ll t = 2ll * ((n - 2) + (m - 2));
    for (int i = 1; i < k + 1; i++) {
        int x, y, c;
        scanf("%d%d%d", &x, &y, &c);
        if (x == 1 || x == n) {
            if (y != 1 && y != m) u++, v ^= c;
        } else if (y == 1 || y == m) {
            u++, v ^= c;
        } else {

        }
    }
    t -= u;
    ll in = (ll)n * m - k - t;

    if (!t) {
        if (!v) printf("%lld\n", qmi(2, in, MOD));
        else puts("0");
    } else {
        printf("%lld\n", qmi(2, in + t - 1, MOD));
    }
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}
posted @ 2025-03-30 02:18  __insomnium  阅读(426)  评论(3)    收藏  举报