题解 | #Kuriyama Mirai and Exclusive Or#

Guess and lies

https://ac.nowcoder.com/acm/contest/11254/A

I - Kuriyama Mirai and Exclusive Or

题意:
序列上两种操作,对异或上,对异或上,问最后序列的样子。

思路:
区间修改,只问最后长啥样,试试看异或差分。操作直接搞就行,操作显得很复杂,看起来只能单点修改。观察这个式子。当时,这个式子等价于,也等价于,看看能否把这个异或的式子加入到异或差分中。那么首先对于这个区间,我们先对其整体异或上,然后问题就转换成了对这个区间异或上。首先肯定不能一个个推过去,这样和前面暴力是没有区别的。设,把异或的值都拿出来,得到。我们以为中间的边界,可以把右边的值写成。相当于从原本要异或的值中取出前一半,复制一份给后一半,同时将后一半的区间整体异或上。对于每个来说,我都能递归到,所以第二步就转换成了对区间的异或修改。这里每一次都递归会显得很多余,我们可以先打个标记,最后从大到小一起转移就行。

每一步完成这样的操作后,注意更新,把他们都加上。最后一步可能会超出我需要修改的右区间,这里我们只需要从大到小枚举,尝试用去更新就行了。因为更新不了,后面填上去的数字在的二进制位上一定在最后一位后面,即一定为,所以也能转换成异或操作。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 6e5 + 7;

bool tag[N][30];
int a[N];

void solve() {
    int n, q;
    cin >> n >> q;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        if (i) a[i] ^= a[i - 1];
    }
    while (q--) {
        int op, l, r, x;
        cin >> op >> l >> r >> x;
        l--, r--;
        if (!op) {
            a[l] ^= x;
            a[r + 1] ^= x;
            continue;
        }
        for (int i = x & -x; l + i <= r + 1; x += i, l += i, i = x & -x) {
            a[l] ^= x;
            a[l + i] ^= x;
            tag[l][__lg(i)] ^= true;
        }
        for (int i = 29; i >= 0; --i) {
            int k = 1 << i;
            if (l + k <= r + 1) {
                a[l] ^= x;
                a[l + k] ^= x;
                tag[l][i] ^= true;
                l += k;
                x += k;
            }
        }
    }
    for (int j = 29; j >= 1; --j) {
        for (int i = 0; i < n; ++i) {
            if (!tag[i][j]) continue;
            tag[i][j - 1] ^= true;
            int k = 1 << (j - 1);
            if (i + k <= n + 1) {
                tag[i + k][j - 1] ^= true;
                a[i + k] ^= k;
            }
            if (i + k * 2 <= n + 1) a[i + k * 2] ^= k;
        }
    }
    for (int i = 0; i < n; ++i) {
        if (i) a[i] ^= a[i - 1];
        cout << a[i] << ' ';
    }
}

int main() {
#ifndef LOCAL
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cout << fixed << setprecision(20);
#endif
    int t = 1;
    while (t--) solve();
    return 0;
}
全部评论

相关推荐

刚刷到字节跳动官方发的消息,确实被这波阵仗吓了一跳。在大家还在纠结今年行情是不是又“寒冬”的时候,字节直接甩出了史上规模最大的转正实习计划——ByteIntern。咱们直接看几个最硬的数,别被花里胡哨的宣传词绕晕了。首先是“量大”。全球招7000多人是什么概念?这几乎是把很多中型互联网公司的总人数都给招进来了。最关键的是,这次的资源分配非常精准:研发岗给了4800多个Offer,占比直接超过六成。说白了,字节今年还是要死磕技术,尤其是产品和AI领域,这对于咱们写代码的同学来说,绝对是今年最厚的一块肥肉。其次是大家最关心的“转正率”。官方直接白纸黑字写了:整体转正率超过50%。这意味着只要你进去了,不划水、正常干,每两个人里就有一个能直接拿校招Offer。对于2027届(2026年9月到2027年8月毕业)的同学来说,这不仅是实习,这简直就是通往大厂的快捷通道。不过,我也得泼盆冷水。坑位多,不代表门槛低。字节的实习面试出了名的爱考算法和工程实操,尤其是今年重点倾斜AI方向,如果你简历里有和AI相关的项目,优势还是有的。而且,转正率50%也意味着剩下那50%的人是陪跑的,进去之后的考核压力肯定不小。一句话总结:&nbsp;27届的兄弟们,别犹豫了。今年字节这是铁了心要抢提前批的人才,现在投递就是占坑。与其等到明年秋招去千军万马挤独木桥,不如现在进去先占个工位,把转正名额攥在手里。
喵_coding:别逗了 50%转正率 仔细想想 就是转正与不转正
字节7000实习来了,你...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务