Codeforces Round 922 (Div. 2)

基本情况

A、B秒了,C二进制拆位处理短板,卡了很久,D没想出来,甚至二分都没考虑。

C. XOR-distance

Problem - C - Codeforces

这题算是给我上了一课,

二进制拆位处理真该好好学学了。

思路

思路很好想,从高位往低位处理:

  • 先找到最高的不同的位
    • 如果是上 \(1\)\(0\),说明结果最高位是正的。
    • 如果是上 \(0\)\(1\),说明结果最高位是正的。
  • 之后找每一个不同的位
    • 如果最高位是正的,就只对 上 \(1\)\(0\) 的情况取反处理。
    • 如果最高位是负的,就只对 上 \(0\)\(1\) 的情况取反处理。
    • 总结:同号取反处理,异号不作处理。

实现

由于第一次遇到这种题,所以啥都是从头开始。

  • 判断 \(x\) 的二进制第 \(k\) 位是什么

我最开始是用了十进制类似处理方法,就每次把这个数左移一,然后按位与一,但是这样会改变数原来的数值。

后面想到了更简便的处理方法,但是用的是原数右移,也是很麻烦。

学习了最合适的方法 x & (1 << k)

原理很显然,算是一个 \(trick\)

其实破题关键点就是这个,我因为这个用的不是最方便的,导致了石山代码。

之后实现就按位处理即可。

void solve()
{
    ll x, y, r;
    cin >> x >> y >> r;
    bool is_high = true;
    ll now = 0;
    for (ll i = 60; i >= 0; i--) {
        bool px = (x & (1LL << i)), py = (y & (1LL << i));//判断第i位的数码
        if (px == py) continue;
        if (is_high) {
            now = (1LL << i) * (px - py);//最高位直接加上,不操作
            is_high = false;
        }
        else {
            if (r >= (1LL << i) && (px - py) * now > 0) {//同号且r还够,进行操作
                r -= (1LL << i);
                now -= (px - py) * (1LL << i);
            }
            else {//异号不用操作
                now += (px - py) * (1LL << i);
            }
        }
    }
    if (now > 0) cout << now << endl;
    else cout << -now << endl;
}

D. Blocking Elements

Problem - D - Codeforces

这题真的是技不如人了。

甚至正解的边都没碰到,一直在想贪心错解。

正解是二分,check时候要用到单调队列优化DP。

目前仅限于理解大体思路,感觉距离这道题还有很大距离,先放着。

posted @ 2024-01-31 16:00  加固文明幻景  阅读(16)  评论(0编辑  收藏  举报