一、异或运算
对底层二进制串进行运算
性质:
假设N为任意实数
性质1:0 ^ N = N
性质2:N ^ N = 0
性质3:异或运算满足交换律与结合律
重点:我们可以将异或运算理解为二进制的无进位相加!也就是说,当两个数异或的时候,如果某一位同为1,则该位为0并且不向前进位。
x⊕y=z ⇒ x⊕z=y
( x ⊕ y ) ⊕ z = x ⊕ ( y ⊕ z )
x ⊕ 0 = x x ⊕ x = 0
x ⊕ b ⊕ b = x ⊕ 0 = x
二、题目
思路:
dp[i]表示下标在[dp[i],i]的元素集合符合条件,并且在[dp[i]+1,i]的元素集合不符合条件。也就是dp[i]是i作为右下标对应的最大左下标。
为什么不以i为左边界?
i以后还有可能出现符合条件的数,但以i为右边界,因为l<r,所以只考虑左边已经出现的数
#include <iostream>
using namespace std;
const int N = 100005;
const int MAXVAL = 2000000;
int a[N];
int pos[MAXVAL];//目前val值的最大下标
int res[N];//左边界
int main()
{
int n, m, x;
cin >> n >> m >> x;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; i++)
{
pos[a[i]] = i;
res[i] = max(res[i - 1], pos[a[i] ^ x]);
}
int l, r;
for(int i = 0; i < m; i++)
{
scanf("%d%d", &l,&r);
if(l <= res[r]) printf("%s\n", "yes");
else printf("%s\n", "no");
}
return 0;
}