Codeforces Round 1049 (Div. 2)(B-E)

贪心问题推式子场

B

邪道打表通过的。
这种数学题对于10x感觉都是转化为10x-1或者类似的东西然后再找性质

C

无论B做什么操作,A都可以直接取消B的操作,所以B会结束游戏,实际上只操作一次。
考虑交换左右端点对答案的贡献是多少,会得到一个含ij的式子,对每个点取最优贡献,然后取最大值。

D

部分贡献是固定的,考虑如何计算新增的贡献。
对于偶数,只需要对所有r求和再减去l+r最小的n/2个值就是答案。
对于奇数,按照偶数做以后枚举不选的区间求最大值。
直接找不选哪个区间我不会。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
// #define int long long
#define endl '\n'
#define pii pair<int, int>
#define ls(x) (x << 1)
 #define rs(x) (x << 1 | 1)
const int N = 2e5 + 7;
int n, m;
pii a[N];
void solve() {
    cin >> n;
    vector<pair<int, pii>> b(n + 1);
    ll ans = 0;
    ll w = 0, k = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].first >> a[i].second;
        b[i].first = a[i].first + a[i].second;
        b[i].second = a[i];
        ans += a[i].second - a[i].first;
        w += a[i].second;
    }                  
    sort(b.begin(), b.end());
    for (int i = 1; i <= (n + 1) / 2; i++) w -= b[i].first;
    k = w;
    if (n % 2) {
        for (int i = 1; i < n / 2 + 1; i++) {
            k = max(k, w + b[i].second.first);
        }
        w += b[n / 2 + 1].first;
        for (int i = n / 2 + 1; i <= n; i++) {
            k = max(k, w - b[i].second.second);
        }
    }
    cout << ans + k << endl;
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int T = 1;
    cin >> T;
    // p10[0] = 1;
    // for (int i = 1; i < 10; i++) p10[i] = p10[i - 1] * 10;
    while(T--) {
        solve();
    }
}

E

posted @ 2025-09-10 11:02  lyrrr  阅读(31)  评论(0)    收藏  举报