Featured image of post Codeforces Round #1049(Div.2)

Codeforces Round #1049(Div.2)

B

题目大意:Alice 和 Bob 玩一个游戏,Alice 给 Bob 一个正整数 $x \le 10^8$。为了赢得游戏,Bob 需要找到另一个正整数 $y \le 10^9$,使得 $x \operatorname{\#} y$ 能被 $x + y$ 整除。这里 $x\operatorname{\#}y$ 表示将整数 $x$ 和 $y$ 按顺序拼接形成的新整数。然而,由于 Bob 太笨,无法找到这样的整数。需要帮助他。可以证明,满足条件的整数 $y$ 总是存在。

数据范围:$1 \le t \le 10^4$,$1 \le x \le 10^8$。

思路:

1
2
3
4
5
6
7
using i128 = __int128_t;
void solve() {
    ll x;
    cin >> x;
    cout << 2 * x << endl;
    return;
}

C

题目大意:给定数组 $a$,定义函数 $f(a)$ 为操作代价加上数组的交错和。Alice 与 Bob 轮流在数组上进行操作或终止游戏,双方最优时需要求最终的函数值。

数据范围:$1 \le t \le 10^4$,$1 \le n \le 2\cdot10^5$,$1 \le a_i \le 10^9$,$\sum n \le 2\cdot10^5$。

思路:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using i128 = __int128_t;
void solve() {
    ll n;
    cin >> n;
    vl a(n);
    rep(i, 0, n - 1) cin >> a[i];
    ll ans = 0;
    rep(i, 0, n - 1) {
        if (i % 2 == 0)
            ans += a[i];
        else
            ans -= a[i];
    }
    ll ans2 = ans;
    ans2 = max(ans2, ans + (n % 2 == 0 ? n - 2 : n - 1));
    set<ll> tem;
    rep(i, 0, n - 1) {
        if (i % 2 == 1)
            tem.insert(2 * a[i] - i);
        else {
            if (!tem.empty()) ans2 = max(ans2, ans + *prev(tem.end()) - (2 * a[i] - i));
        }
    }
    tem.clear();
    rep(i, 0, n - 1) {
        if (i % 2 == 1) {
            if (!tem.empty()) ans2 = max(ans2, ans + 2 * a[i] + i - *tem.begin());
        } else {
            tem.insert(2 * a[i] + i);
        }
    }
    cout << ans2 << endl;
    return;
}

D

题目大意:给你 $n$ 个在数轴上的线段,第 $i$ 条线段表示为 $[l_i, r_i]$。初始时,所有线段都是未标记的。你将不断重复以下操作,直到没有未标记的线段为止: 1. 在第 $k$ 次操作中,如果目前有至少两条未标记的线段,任选两条未标记的线段 $[l_i, r_i]$ 和 $[l_j, r_j]$,将这两条线段都标记,并新增一条满足以下条件的标记线段 $[x_k, y_k]$: - $l_i \leq x_k \leq r_i$, - $l_j \leq y_k \leq r_j$, - $x_k \leq y_k$。2. 如果只剩一条未标记的线段,则将其标记。需要求出执行完所有操作后,所有标记线段的长度之和的最大可能值。

数据范围:$1 \le t \le 10^4$,$1 \leq n \leq 2 \times 10^5$,$1 \leq l_i \leq r_i \leq 10^9$,$\sum n \le 2 \times 10^5$。

思路:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using i128 = __int128_t;
void solve() {
    ll n;
    cin >> n;
    vector<pll> ma(n);
    rep(i, 0, n - 1) cin >> ma[i].first >> ma[i].second;
    if (n == 1) {
        cout << ma[0].second - ma[0].first << endl;
        return;
    }
    ll ans = 0;
    rep(i, 0, n - 1) ans += ma[i].second - ma[i].first;
    sort(all(ma), [&](const pll& x, const pll& y) { return x.first + x.second < y.first + y.second; });
    if (n % 2 == 0) {
        ll l = 0, r = n - 1;
        while (l < r) {
            ans += ma[r].second - ma[l].first;
            l++, r--;
        }
        cout << ans << endl;
        return;
    }
    vl pre1(n);
    vl pre2(n);
    pre1[0] = ma[0].first, pre2[n - 1] = ma[n - 1].second;
    rep(i, 1, n - 1) pre1[i] = pre1[i - 1] + ma[i].first;
    rep(i, 1, n - 1) pre2[i] = pre2[i - 1] + ma[i].second;
    ll ans2 = ans;
    rep(i, 0, n - 1) {
        if (i < n / 2)
            ans2 = max(ans2, ans + pre2[n - 1] - pre2[n / 2] - pre1[n / 2] + ma[i].first);
        else if (i == n / 2)
            ans2 = max(ans2, ans + pre2[n - 1] - pre2[n / 2] - pre1[n / 2 - 1]);
        else
            ans2 = max(ans2, ans + pre2[n - 1] - pre2[n / 2 - 1] - pre1[n / 2 - 1] - ma[i].second);
    }
    cout << ans2 << endl;
    return;
}