CF252A - Little Xor

CF252A - Little Xor

题目

Little Xor - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

异或的部分性质:

  • a ^ a = 0,a ^ 0 = a
  • 异或具有交换律和结合律,a ^ b ^ c <=> (a ^ b) ^ c

思路

  • 设序列为arr[n],ai表示下标为i的值,当 n = 6, 有 a0, a1, a2, a3, a4, a5
  • 设xorPre[n]为异或前缀和,即xorPre[0] = a0, xorPre[1] = a0 ^ a1, xorPre[2] = a0 ^ a1 ^ a2 …
  • [2, 4]区间的异或和为 xorSum = a2 ^ a3 ^ a4,因为 a0 ^ a1 ^ a0 ^ a1 = (a0 ^ a0) ^ (a1 ^ a1) = 0
  • 可变换为 xorSum = a0 ^ a1 ^ a0 ^ a1 ^ a2 ^ a3 ^ a4 = (a0 ^ a1) ^ (a0 ^ a1 ^ a2 ^ a3 ^ a4)
  • 即xorSum = xorPre[1] ^ xorPre[4]
  • 拓展到任意区间[l, r], xorSum = xorPre[l - 1] ^ xorPre[r]
  • 题目要求连续段中最大的异或和,我们枚举每一个区间[l, r]即可求出最大异或和

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 107;

// 异或前缀和数组
int xorPre[N];
int n;
int ans;

int main() {
    cin >> n;
    // 从下标1开始可以避免冗余的判断,当 i = 1 时 xorPre[1] = xorPre[0](0) ^ xorPre[1] = xorPre[1]
    for (int i = 1; i <= n; i++) {
        // 读入当前数值
        cin >> xorPre[i];
        // 与前一位的异或前缀和异或,得到当位异或和
        xorPre[i] ^= xorPre[i - 1];
    }
    // 枚举左端点i
    for (int i = 1; i <= n; i++) {
        // 枚举右端点,并且j >= i区间才合法
        for (int j = i; j <= n; j++) {
            // 当前区间异或和与ans取最大值
            ans = max(ans, xorPre[j] ^ xorPre[i - 1]);
        }
    }
    // 输出答案
    cout << ans << endl;
    return 0;
}

复杂度分析

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值