I. Integer Reaction

Problem - I - Codeforces

在这里插入图片描述

看到最小值最大值,二分答案。

思路:每次二分时开两个集合,分别表示 0 0 0颜色和 1 1 1颜色。如果是 c c c颜色,先将值存入 c c c颜色,之后在 ! c !c !c颜色中找大于等于 m i d − a mid - a mida的值。

  • 如果找到:删除 c c c颜色中一个值为 a a a的元素和 ! c !c !c颜色中一个值为大于等于 m i d − a mid - a mida的元素。
  • 没有找到:找不大于 m i d − a mid - a mida中最大的值,判断该值是否存在,如果存在则返回 f a l s e false false;否则继续处理。

对于C++的集合erase函数来说:

  • setset中的元素是不同的,非多重集。
  • multiset:虽然元素可以是多个,但是按key删除是将集合中key相等的都删除。可以按迭代器删除。

这里提供另一种:将set中的key用元组表示,second用下标表示。这样即使first值相同,但是second值不同,实现了每次只删除一个元素。

代码如下:

#include "bits/stdc++.h"
using namespace std;
using LL = long long;
int main()
{
    int n; cin>>n;
    vector<int> a(n), c(n);
    for(auto &t: a) cin>>t;
    for(auto &t: c) cin>>t;
    LL l = 0, r = 1e9;
    auto check = [&](LL mid) -> bool {
        set<pair<LL,LL>> s[2];
        for(int i = 0; i < n; ++i) {
            s[c[i]].insert({a[i], i});
            if(s[!c[i]].size()) {
                auto pos = s[!c[i]].lower_bound({mid - a[i], -1});
                if(pos == s[!c[i]].end()) {
                    auto it = pos--;
                    if(it != s[!c[i]].begin()) {
                        return false;
                    }
                } else {
                    s[!c[i]].erase(pos);
                    s[c[i]].erase({a[i], i});
                }
            }
        }
        return true;
    };
    while(l < r) {
        LL mid = l + r + 1 >> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }
    cout<<l<<endl;
}
  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

golemon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值