跳转至

Codeforces Round 1028 (Div. 2)

2025-05-31

pViFebD.png

A

哈哈哈,错了一发,因为我以为 ab 都是第一个人的。。。读题确实要仔细点

// Date: 2025-05-31
// Time: 22:36:31
void ChatGptDeepSeek()
{
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    if(min(a, c) >= min(b, d)) cout << "Gellyfish\n";
    else cout << "Flower\n";
}

B

因为是排列,所以加的两个位置,必然至少有一个数字是前缀的最大值。其实不需要快速幂,拿个数组记一下就行。

// Date: 2025-05-31
// Time: 22:43:12
constexpr int mod = 998244353;

ll ksm(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1)
            res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
void ChatGptDeepSeek()
{
    int n;
    cin >> n;
    vi p(n), q(n), pos1(n), pos2(n), r(n), mx(n);
    for(int i = 0; i < n; i++){
        cin >> p[i];
        pos1[p[i]] = i;
    }
    for(int i = 0; i < n; i++){
        cin >> q[i];
        pos2[q[i]] = i;
    }
    mx[0] = max(p[0], q[0]);
    for(int i = 1; i < n; i++){
        mx[i] = max(mx[i - 1], max(p[i], q[i]));
    }
    for(int i = 0; i < n; i++){
        int x = 0;
        if(pos1[mx[i]] <= i)
            cmax(x, q[i - pos1[mx[i]]]);
        if(pos2[mx[i]] <= i)
            cmax(x, p[i - pos2[mx[i]]]);
        r[i] = (ksm(2, mx[i]) + ksm(2, x)) % mod;
        cout << r[i] << " \n"[i + 1 == n];
    }
}

C

拿个简单的dp或者bfs就行,其实就是要算最少多少个数字的gcd可以等于 \(g\)。然后其余的数字只需要跟这个数字一起操作一次就会变成 \(g\)

后面重交发现 std::gcd 比 __gcd 快好多。然后取 gcd 还是挺费时间的。

// Date: 2025-05-31
// Time: 22:53:29
void ChatGptDeepSeek()
{
    int n;
    cin >> n;
    vi dp(5000 + 1, INF), a(n + 1);
    int g = 0;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        dp[a[i]] = 0;
        g = gcd(g, a[i]);
    }
    if(*min_element(ALL(a)) == g){
        cout << n - count(ALL(a), g) << '\n';
        return;
    }
    for(int i = 1; i <= n; i++){
        // vi ndp(dp);
        for(int j = 1; j <= 5000; j++){
            if(dp[j] != INF)
                cmin(dp[gcd(j, a[i])], dp[j] + 1);
        }
        // dp = ndp;
    }
    cout << dp[g] + n - 1 << '\n';
}

D

逆着考虑会好很多。就是我们先看后进行的操作。

先弄一个数组 \(l\) 表示对 \(c_i\) 的限制,刚开始 \(l = b\)。每次修改操作,意味着 \(l_x \ge l_z\), \(l_y \ge l_z\),然后 \(l_z = 0\)。我们就跟着改就行,最终的答案就是数组 \(l\)。好像完全没有问题,代码很简单,但是自己想感觉根本不知道从哪开始。

// Date: 2025-06-06
// Time: 08:05:35
void ChatGptDeepSeek()
{
    int n, q;
    cin >> n >> q;
    vi b(n + 1), l(n + 1);
    for(int i = 1; i <= n; i++){
        cin >> b[i];
        l[i] = b[i];
    }
    vc<array<int, 3>> op(q);
    for(int i = q - 1; i >= 0; i--){
        cin >> op[i][0] >> op[i][1] >> op[i][2];
    }
    for(auto [x, y, z] : op){
        cmax(l[x], l[z]);
        cmax(l[y], l[z]);
        if(z != x && z != y)
            l[z] = 0;
    }
    vi c(l);
    for(int i = q - 1; i >= 0; i--){
        auto [x, y, z] = op[i];
        c[z] = min(c[x], c[y]);
    }
    if(b != c){
        cout << "-1\n";
        return;
    }
    for(int i = 1; i <= n; i++){
        cout << (l[i] ? l[i] : 1) << " \n" [ i == n];
    }
}