Codeforces Round 892 (Div. 2) ABCDE

A. United We Stand
code

const int N = 1e6 + 10;
int a[N];
int n;
vector<int> b, c;
void solve(){
    cin >> n;
    for(int i = 1; i <= n; i ++)
        cin >> a[i];
    sort(a + 1, a + 1 + n);
    b.clear();
    c.clear();
    for(int i = 1; i <= n; i ++){
        if(a[i] != a[n])
            b.pb(a[i]);
        else
            c.pb(a[i]);
    }
 
    if(b.size() == n || !b.size())
        cout << -1 << endl;
    else{
        cout << b.size() << ' ' << c.size() << endl;
        for(auto i : b) cout << i <<' ';
        cout << endl;
        for(auto j : c) cout << j << ' ';
        cout << endl;
    }
}  

B. Olya and Game with Arrays
code

void solve(){
    int n;
    cin >> n;
    vector<int> a[n + 1], b;
    ll ans = 0, minn = LNF;
    for(int i = 1; i <= n; i ++){
        int m; cin >> m;
        for(int j = 1; j <= m; j ++){
            int k; cin >> k;
            a[i].pb(k);
        }
        sort(a[i].begin(), a[i].end());
        ans += a[i][1];
        minn = min(minn, a[i][1]);
        b.pb(a[i][0]);
    }
    sort(b.begin(), b.end());
    cout << ans - minn + b[0] << endl;
}   

C. Another Permutation Problem
思路:
这个东西一眼是一个单峰函数,那么就可以二分
打表发现,峰值时,是一个递增的排列,后面的几个数字反转的结果
然后就可以二分这个后缀的长度

(我不会二分,二分边界调一万年,就范围内暴力check了)
code

int n;
int check(int mid){
    ll res = 0;
    for(int i = 1; i < mid; i ++)
        res += i * i;
    int l = mid, r = n;
    int maxn = 0;
    while(l <= r){
        if(l == r)
            res += l * r;
        else
            res += l * r * 2;
        maxn = max(maxn, l * r);
        l ++, r --;
    }
    return res - maxn;
}
 
void solve(){
    cin >> n;
    int l = 1, r = n;
    while(r - l >= 3){
        int midl = (l + l + r) / 3, midr = (l + r + r) / 3;
        if(check(midl) < check(midr))
            l = midl;
        else r = midr;
    }
    int ans = 0;
    for(int i = l; i <= r; i ++)
        ans = max(check(i), ans);
    cout << ans << endl;
}  

D. Andrey and Escape from Capygrad
思路:首先可以发现, [ l , r ] [l,r] [l,r]中的 r r r 是没啥用的, [ a , b ] [a,b] [a,b] 中的 a a a 是没啥用的
这样的话,就把区间 [ l , b ] [l,b] [l,b] 当作一个可行区间,sort之后去二分就可以了
(全场写了两个二分,幸亏这个二分不用手写,哭了,真不会写二分)
code

const int N = 1e6 + 10;
PII a[N];
vector<PII> v;
int n;
 
void solve(){
    cin >> n;
    v.clear();
    for(int i = 1; i <= n; i ++){
        int l, r, L, R;
        cin >> l >> r >> L >> R;
        a[i] = {l, R};
    }
 
    sort(a + 1, a + 1 + n);
    int l = LNF, r = 0;
    for(int i = 1; i <= n; i ++){
        if(a[i].x > r){
            v.pb({l, r});
            l = a[i].x;
        }
        r = max(r, a[i].y);
    }
    v.pb({l, r});
    int q;
    cin >> q;
    while(q --){
        int k; cin >> k;
        PII s = {k, LNF};
        auto idx = upper_bound(v.begin(), v.end(), s);
        if(idx == v.begin())
            cout << k << ' ';
        else
            cout << max((*(-- idx)).y, k) << ' ';
    }
    cout << endl;
} 

E. Maximum Monogonosity
思路:
a b s ( s 1 i − s 2 i ) abs(s1_i-s2_i) abs(s1is2i) 变成 m a x ( s 1 i − s 2 i , s 2 i − s 1 i ) max(s1_i - s2_i, s2_i-s1_i) max(s1is2i,s2is1i) 乍一看可能觉得没区别,但是转换成这个样子就可以去dp了
所以 f i j f_{ij} fij 就表示前 i i i 个中选 j j j 个的最大花费
那么可以分成四种情况
s 1 i + s 2 i s1_i+s2_i s1i+s2i
s 1 i − s 2 i s1_i-s2_i s1is2i
− s 1 i + s 2 i -s1_i+s2_i s1i+s2i
− s 1 i + s 2 i -s1_i+s2_i s1i+s2i
我令 i d id id 表示 i d = i − j id=i-j id=ij 所以, a i d a_{id} aid 表示前 i i i 个数中选 j j j 个然后加上 s 1 i + s 2 i s1_i+s2_i s1i+s2i 的最大值
同理 b i d , c i d , d i d b_{id},c_{id},d_{id} bid,cid,did
所以状态转移式为
f [ i ] [ j ] = m a x ( f [ i ] [ j ] , a [ i d ] − s 1 [ i ] − s 2 [ i ] , b [ i d ] − s 1 [ i ] + s 2 [ i ] , c [ i d ] + s 1 [ i ] − s 2 [ i ] , d [ i d ] + s 1 [ i ] + s 2 [ i ] ) f[i][j] = max(f[i][j], a[id] - s1[i] - s2[i],b[id] - s1[i] + s2[i], c[id] + s1[i] - s2[i], d[id] + s1[i] + s2[i]) f[i][j]=max(f[i][j],a[id]s1[i]s2[i],b[id]s1[i]+s2[i],c[id]+s1[i]s2[i],d[id]+s1[i]+s2[i])

code

const int N = 3010;
ll a[N], b[N], c[N], d[N];
ll s1[N], s2[N];
ll f[N][N];
int n, k;

void solve(){
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) cin >> s1[i];
    for(int i = 1; i <= n; i ++) cin >> s2[i];
    for(int i = 0; i <= n; i ++)
        for(int j = 0; j <= k; j ++)
            f[i][j] = 0;
    for(int i = 0; i <= n; i ++)
        a[i] = b[i] = c[i] = d[i] = -LNF;
    a[0] = s1[1] + s2[1];
    b[0] = s1[1] - s2[1];
    c[0] = - s1[1] + s2[1];
    d[0] = - s1[1] - s2[1];

    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= k; j ++)
            f[i][j] = max(f[i - 1][j], f[i - 1][j - 1] + 2 * abs(s1[i] - s2[i]));
        for(int j = 0; j <= min(i, k); j ++){
            int id = i - j;
            f[i][j] = max(max(f[i][j],
                            a[id] - s1[i] - s2[i]),
                        max({b[id] - s1[i] + s2[i],
                            c[id] + s1[i] - s2[i],
                            d[id] + s1[i] + s2[i]}));
        }
        for(int j = 0; j <= min(i, k); j ++){
            int id = i - j;
            a[id] = max(a[id], f[i][j] + s1[i + 1] + s2[i + 1]);
            b[id] = max(b[id], f[i][j] + s1[i + 1] - s2[i + 1]);
            c[id] = max(c[id], f[i][j] - s1[i + 1] + s2[i + 1]);
            d[id] = max(d[id], f[i][j] - s1[i + 1] - s2[i + 1]);
        }
    }
    cout << f[n][k] << endl;
}   
抱歉,根据提供的引用内容,我无法理解你具体想要问什么问题。请提供更清晰明确的问题,我将竭诚为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【CodeforcesCodeforces Round 865 (Div. 2) (补赛)](https://blog.csdn.net/t_mod/article/details/130104033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值