发烧了几天,现在脑子清醒点了,做道题。此题目出自第十三届蓝桥杯C/C++的A/C/研究生组。
AcWing 4645. 选数异或
题目描述
给定一个长度为 \(n\) 的数列 \(A_1,A_2,⋅⋅⋅,A_n\) 和一个非负整数 \(x\),给定 \(m\) 次查询,每次询问能否从某个区间 \([l,r]\) 中选择两个数使得他们的异或等于 \(x\)。
输入格式
输入的第一行包含三个整数 \(n,m,x\)。
第二行包含 \(n\) 个整数 \(A1,A2,⋅⋅⋅,An\)。
接下来 \(m\) 行,每行包含两个整数 \(l_i,r_i\) 表示询问区间 \([l_i,r_i]\)。
输出格式
对于每个询问,如果该区间内存在两个数的异或为 \(x\) 则输出 \(yes\),否则输出 \(no\)。
数据范围
对于 \(20\%\) 的评测用例,\(1≤n,m≤100\);
对于 \(40\%\) 的评测用例,\(1≤n,m≤1000\);
对于所有评测用例,\(1≤n,m≤100000,0≤x<220\),\(1≤l_i≤r_i≤n\),\(0≤A_i<220\)。
输入样例
4 4 1
1 2 3 4
1 4
1 2
2 3
3 3
输出样例
yes
no
yes
no
样例解释
显然整个数列中只有 \(2,3\) 的异或为 \(1\)。
思路
如果 \(a ⊕ b = x\),则 \(b ⊕ x = a\)。
状态表示:哈希表 \(last\) 存储 \(a_i\) 的位置,\(f[i]\) 表示 \(1-i\) 中与 \(a_i\) 构成异或数对的最大下界,即 \(a_j, 1≤j≤i-1, a_j ⊕ a_i = x\),最大下界即最大的 \(j\)。
状态计算:每次输入 \(a_i\),找到 \(a_i ⊕ x\) 的位置,\(f[i]=max(f[i-1], last[a_i ⊕ x])\)。
在区间判断时,如果 \(f[r]≥l\),也就是存在最大下界在区间内,至少存在一个数对。
C++代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, x;
map<int, int> last;
int f[N];
int main()
{
cin >> n >> m >> x;
for (int i = 1; i <= n; i ++)
{
int a;
cin >> a;
last[a] = i;
f[i] = max(f[i - 1], last[a ^ x]);
}
while (m --)
{
int l, r;
cin >> l >> r;
if (f[r] >= l) puts("yes");
else puts("no");
}
return 0;
}
标签:30AcWing,last,no,int,样例,异或,2023,yes,2022.12
From: https://www.cnblogs.com/Cocoicobird/p/17016064.html