喜及眩 发表于 前天 16:19

Educational Codeforces Round 177 (Rated for Div. 2)

A. Cloudberry Jam

卡累利阿森林中最珍贵的浆果是云莓。为了用云莓制成果酱,我们需要取等量的云莓和糖,然后烹煮。也就是说,如果你有 \(2\) 公斤的云莓,你需要 \(2\) 公斤的糖。然而,使用 \(2\) 公斤云莓和 \(2\) 公斤糖制作出的果酱,并不会得到 \(4\) 公斤的果酱,而仅仅只有 3 公斤,因为在烹煮过程中会有部分果酱蒸发。具体来说,在标准烹煮过程中,果酱会蒸发掉四分之一(25%)。为了制作 \(n\) 个每个重 \(3\) 公斤的果酱罐头,需要多少公斤的云莓?
\(n \leq 10^8\)
每两公斤云莓生产三公斤果酱,答案就是 \(n \times 2\)。
代码#include <bits/stdc++.h>

using namespace std;

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

int main() {
    int T;
    cin >> T;
    while (T--) {
      cin >> n;
      printf("%d\n", n << 1);
    }
    return 0;
}C. Disappearing Permutation

给定一个从 \(1\) 到 \(n\) 的整数排列,这是一种大小为 \(n\) 的数组,其中每个整数从 \(1\) 到 \(n\) 恰好出现一次。现在给定一个排列 \(p\),它包含从 \(1\) 到 \(n\) 的整数。你需要处理 \(n\) 个查询。
在第 \(i\) 个查询中,你将 \(p_{d_i}\) 替换为 \(0\)。每个元素恰好被替换为 \(0\) 一次。查询中所做的更改是累积的,也就是说,在第 \(i\) 个查询之后,所有的整数 \(p_{d_1}, p_{d_2}, \ldots, p_{d_i}\) 都变为零。
每次查询之后,你需要找出修复数组所需的最小操作次数;换句话说,将当前数组转换为任意从 \(1\) 到 \(n\) 的排列(可能转换为原排列 \(p\),也可能转换为其他排列)。
你可以执行的修复数组的操作是:
选择一个整数 \(i\)(\(1\le i\le n\)),将数组的第 \(i\) 个元素替换为 \(i\)。
注意,每个查询的答案都是独立计算的,也就是说,你实际上并不执行任何操作,只需要计算出最小的操作次数即可。
\(n \leq 10^5\)
对每个位置 \(i\) 向 \(p_i\) 连一条有向边,这样形成的图会分成若干不相交的环。某个点 \(i\) 如果被替换成了 \(0\) 或者其他数,那么数组就会缺失 \(p_i\),\(i\) 的出边指向的点 \(p_i\) 就必须被操作。对于每一个环,如果环中存在至少一个点被替换成了 \(0\),那么环上所有点都需要进行操作。
代码#include <bits/stdc++.h>

using namespace std;

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


ll x;
void solve() {
    ll sum = 0, res = 0;
    for (int i = 1; i < n + 1; i++) sum += w;
    ll r = sum * m;
    for (int i = 1; i <= m; i++) {
      if (r - sum + w >= x) res += n;
      else {
            for (int j = 1; j <= n; j++) {
                res += r >= x;
                r -= w;
            }
            break;
      }
      r -= sum;
    }
    printf("%lld\n", res);
}

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

你想构造一个由小写拉丁字母组成的字符串 \(s\),使得满足以下条件:
对于所有满足 \(s_i=s_j\) 的索引对 \(i\) 和 \(j\),它们之间的差值是偶数,即 \(|i-j|\mod2=0\)。
构造任意字符串太简单了,所以你会得到一个包含 26 个数字的数组 \(c\) —— 表示字符串 \(s\) 中每个字母要求出现的次数。也就是说,对于每个 \(i\in\),拉丁字母表中的第 \(i\) 个字母应恰好出现 \(c_i\) 次。
你的任务是计算满足所有这些条件的不同字符串 \(s\) 的数量。由于答案可能非常大,请将结果对 \(998244353\) 取模。
\(c \leq 5 \times 10^5\)
题目的限制等价于对于每一个字符,要么所有都放到奇数位置,要么所有都放到偶数位置。考虑对每一个字符放置位置的奇偶性分配好后,令 \(N_{odd}\) 为奇数位置数量,\(N_{even}\) 为偶数位置数量,\(S\) 为选择放在奇数位置的字符的集合,不同的字符串个数有 \(\frac{N_{\mathrm{odd}}!}{\prod_{i\in S} c_i!} \times \frac{N_{\mathrm{even}}!}{\prod_{i\notin S} c_i!} = \frac{N_{\mathrm{odd}}! \cdot N_{\mathrm{even}}!}{\prod_{i=1}^{26} c_i!}\) 个。合法的奇偶位置分配方案数可以通过 dp 计算。
代码#include <bits/stdc++.h>

using namespace std;

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


int d;
bool st;
void dfs(int r) {
    res++;
    st = 1;
    if (!st]) dfs(w);
}

void solve() {
    memset(st, 0, sizeof(bool) * (n + 10));
    res = 0;
    for (int i = 1; i < n + 1; i++) {
      if (!st]) dfs(d);
      printf("%lld ", res);
    }
    puts("");
}

int main() {
    int T;
    cin >> T;
    while (T--) {
      cin >> n;
      for (int i = 1; i < n + 1; i++) scanf("%d", w + i);
      for (int i = 1; i < n + 1; i++) scanf("%d", d + i);
      solve();
    }
    return 0;
}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Educational Codeforces Round 177 (Rated for Div. 2)