计蒜客 A1607 贪心 + 线性基

题意

传送门 计蒜客 A1607 XOR

题解

不考虑 k k k 时,查询区间子序列异或最大值,即 Codeforces 1100F ,枚举右界,贪心地使位数高的线性基出现的位置尽可能地晚,最后处理包含在查询区间的线性基即可。

本题目标是最大化 k k k 与区间某个子序列异或和的按位或。考虑按位或的性质,若 k k k i i i 位为 1 1 1,那么不论异或和是什么,结果的第 i i i 位都是 1 1 1。那么将所有 a i a_i ai 按位与上 k k k 的按位反转,问题就转换为求解最大化不考虑 k k k 的最大异或值。

#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 1E4 + 5, MAXLG = 27;
int T, N, Q, K, A[MAXN];
int B[MAXN][MAXLG], lst[MAXN][MAXLG];

void insert(int b[], int lst[], int x, int d)
{
    for (int i = MAXLG - 1; i >= 0; --i)
        if (x >> i & 1)
        {
            if (b[i] > 0)
            {
                if (lst[i] < d)
                    swap(b[i], x), swap(lst[i], d);
                x ^= b[i];
            }
            else
            {
                b[i] = x, lst[i] = d;
                break;
            }
        }
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> T;
    while (T--)
    {
        cin >> N >> Q >> K;
        for (int i = 0; i < N; ++i)
            cin >> A[i], A[i] &= ~K;
        memset(B, 0, sizeof(B));
        for (int i = 0; i < N; ++i)
        {
            if (i > 0)
                for (int j = MAXLG - 1; j >= 0; --j)
                    B[i][j] = B[i - 1][j], lst[i][j] = lst[i - 1][j];
            insert(B[i], lst[i], A[i], i);
        }
        while (Q--)
        {
            int l, r;
            cin >> l >> r;
            --l, --r;
            int res = 0;
            for (int i = MAXLG - 1; i >= 0; --i)
                if (!(res >> i & 1) && lst[r][i] >= l)
                    res ^= B[r][i];
            res |= K;
            cout << res << '\n';
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值