2023.1.2选数异或

给定一个长度为 n n n 的数列 A 1 , A 2 , ⋅ ⋅ ⋅ , A n A_{1},A_{2},⋅⋅⋅,A_{n} A1,A2,,An 和一个非负整数 x x x,给定 m m m 次查询,每次询问能否从某个区间 [ l , r ] [l,r] [l,r] 中选择两个数使得他们的异或等于 x x x

输入格式
输入的第一行包含三个整数 n , m , x n,m,x n,m,x

第二行包含 n n n 个整数 A 1 , A 2 , ⋅ ⋅ ⋅ , A n A_{1},A_{2},⋅⋅⋅,A_{n} A1,A2,,An

接下来 m m m 行,每行包含两个整数 l i , r i l_{i},r_{i} li,ri 表示询问区间 [ l i , r i ] [l_{i},r_{i}] [li,ri]

输出格式
对于每个询问,如果该区间内存在两个数的异或为 x x x 则输出 yes,否则输出 no

数据范围
对于 20 20% 20 的评测用例, 1 ≤ n , m ≤ 100 1≤n,m≤100 1n,m100
对于 40 40% 40 的评测用例, 1 ≤ n , m ≤ 1000 1≤n,m≤1000 1n,m1000
对于所有评测用例, 1 ≤ n , m ≤ 100000 , 0 ≤ x < 220 , 1 ≤ l i ≤ r i ≤ n , 0 ≤ A i < 220 1≤n,m≤100000,0≤x<220,1≤l_{i}≤r_{i}≤n,0≤A_{i}<220 1n,m1000000x<2201lirin0Ai<220

在这里插入图片描述
题解

  1. a ⊕ b = x ⟺ a ⊕ b ⊕ x = 0 ⟺ a ⊕ x = b a⊕b=x⟺a⊕b⊕x=0⟺a⊕x=b ab=xabx=0ax=b
    因此对于一个数 a a a, 与 a a a配对的数可以直接计算得出, 即为 a ⊕ x a⊕x ax
  2. 使用闫氏DP分析法:

在这里插入图片描述

代码实现
用哈希表 l a s t [ X ] last[X] last[X]记录数值X最后一次出现时的位置下标, dp[i]的求法是: 若 a i ⊕ x a_{i}⊕x aix最后一次出现的下标要大于dp[i-1], 则
d p [ i ] = l a s t [ a i ⊕ x ] dp[i] = last[ai⊕x] dp[i]=last[aix], 否则 d p [ i ] = d p [ i − 1 ] dp[i] = dp[i-1] dp[i]=dp[i1]


d p [ i ] = m a x ( d p [ i − 1 ] , l a s t [ a i ⊕ x ] ) dp[i]=max(dp[i−1],last[a_{i}⊕x]) dp[i]=max(dp[i1],last[aix])

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int dp[N], n, m, x;

int main() {
    cin >> n >> m >> x;
    unordered_map<int, int> last;
    for(int i=1; i<=n; i++) {
        int a; cin >> a;
        dp[i] = max(dp[i-1], last[x ^ a]);
        //这句应该放到后面, 否则当x=0时会不正确(当x等于0时dp[i] = i, 但是要选两个不同位置的数)
        //更正于2023/01/01
        last[a] = i;
    }

    while (m -- ) {
        int l, r; cin >> l >> r;
        cout << (dp[r] >= l ? "yes" : "no") << endl;
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Next---YOLO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值