暴力解法,TLE了(呜呜呜呜)

#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;const int N = 1e5 + 10;int n, m, x;
int a[N];int main()
{scanf("%d%d%d", &n, &m, &x);for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);while (m --){int l, r;scanf("%d%d", &l, &r);bool flag = false;for (int i = l; i <= r; ++ i){for (int j = i + 1; j <= r; ++ j){if ((a[i] ^ a[j]) == x){flag = true;printf("yes\n");break;}}if (flag) break;}if (!flag) printf("no\n");}return 0;
}

正解:(今天玩累了,明天再写解析吧,嘿嘿)

------------------------------------分割线--------------------------------------------

如何快速判断每个询问是yes或no?

异或对我们在枚举时可以枚举后一个位置(固定枚举后面这个数),这样的话每次找配对数就去左边去找,假设我们当前枚举到b了,那是否在b左边存在一个a,使得a ^ b = x,根据异或运算的性质,我们可以把a算出来,即a = x ^ b

原问题,在这个区间当中,b左边是否存在一个数与b配对 <==等价于==>   在这个区间中是否在b左边存在一个数是x ^ b

在b的左边与b配对的数可能会有很多,我们现在要找的是在给定的区间中存不存在这样的数,所以我们可以预处理一下,对于每个数预处理出来它左边离它最近的一个可以和它配对的数

设 f (i) 表示 在a[i] 左边与 a[i] 配对的最近的一个数的下标,那么我们可以通过判断 f (i) 是否在L-R之间,就可以判断是否存在与a[i] 配对的数。由于配对数右边这个数,是可以遍历整个区间的,那么整个区间内只要存在一个数和它配对的数是在一个区间里面就可以。

相当于是L <= i <= R(i为配对数右边这个数的下标),只要有L <= f(i) <= R(f(i) 为a[i] 左边与 a[i] 配对的最近的一个数的下标),就表示这个区间存在配对数,但是这样的话,L和R都是可以取遍1-n的,又是n^2级别的算法,所以我们需要优化一下。

我们发现,如果i小于L(即i在这个区间左边的话),它对应的f(i)一定不是在这个区间里面的。

所以,L<=i<=R,是否有L<=f(i)<=R 等价于 1<=i<=R,是否有L<=f(i)<=R

由于f(i) <= i <= R,所以f(i) <= R 一定成立,

所以1<=i<=R,是否有L<=f(i)<=R 又等价于 1<=i<=R,是否有f(i) >= L

在1-R之间是否存在一个i,使得它对应的f(i)是大于等于L的

(如果在前面这些数中存在某一个数大于等于某个数的话  等价于  前面这些数中的最大值大于等于这个数)

我们可以预处理一个数组g[i],g[i] = max{f(1), f(2), ... , f(i)}

最终问题 L-R 存在配对的数对 等价于 1-R中f(i)的最大值即g[R]是否大于等于L (这一步是O(1))

g[i] 如何去算?我们知道与a[i]配对的数是a[i] ^ x,要找到a[i] 左边最靠右的值为a[i] ^ x的数,想去查找某个数的位置的话,我们可以用哈希表,本题a[i]和x都在2^20以内,所以a[i]^x也在2^20以内,所以我们可以开一个数组来存储每个数最靠右的位置,这样的话,f(i)就可以表示出来了,g[i]可以递推出来(时间复杂度是O(n)),g[i] = max{g(i - 1), f(i)}

#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;const int N = 100010, M = (1 << 20) + 10;int n, m, x;
int last[M], g[N]; // last[x]记录数值x最后一次出现时的位置下标int main()
{scanf("%d%d%d", &n, &m, &x);for (int i = 1; i <= n; ++ i){int a;scanf("%d", &a);g[i] = max(g[i - 1], last[a ^ x]);last[a] = i;}while (m --){int l, r;scanf("%d%d", &l, &r);if (g[r] >= l) puts("yes");else puts("no");}return 0;
}

还有一种理解方式,令dp[i]为[1, i]区间中所有数对中的最大下界,dp[r]的含义是当查询区间[l, r], 右边界为r时, 至少包含一个数对时的左边界最大值, 所以如果l小于等于这个左边界最大值, [l, r]区间内就至少有一个数对。

哈希表last[x]记录数值x最后一次出现时的位置下标dp[i]的求法是: 若a[i]⊕x最后一次出现的下标要大于dp[i-1], 则dp[i] = last[a[i]⊕x], 否则dp[i] = dp[i-1]此处重申dp[i]的含义是[1, i]区间中所有数对中的最大下界

#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;const int N = 100010, M = (1 << 20) + 10;int dp[N], last[M];
int n, m, x;int main()
{scanf("%d%d%d", &n, &m, &x);for (int i = 1; i <= n; ++ i){int a;scanf("%d", &a);dp[i] = max(dp[i - 1], last[a ^ x]);last[a] = i;}while (m --){int l, r;scanf("%d%d", &l, &r);if (dp[r] >= l) puts("yes");else puts("no");}return 0;
}

Acwing-4645. 选数异或相关推荐

  1. AcWing 4801 选数(二维费用背包的建立)

    AcWing 4180.选数字 问题描述: 给定 n 个整数 a1,a2,-,ana_1,a_2,-,a_na1​,a2​,-,an​. 请你从中选取恰好 k 个数,要求选出的数的乘积的末尾 0 的数 ...

  2. 蓝桥杯2022年第十三届省赛真题-选数异或

    题目描述 给定一个长度为 n 的数列 A1, A2, · · · , An 和一个非负整数 x,给定 m 次查询, 每次询问能否从某个区间 [l,r] 中选择两个数使得他们的异或等于 x . 输入 输 ...

  3. BZOJ3930: [CQOI2015]选数

    BZOJ3930: [CQOI2015]选数 Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案. 小z很好奇这样选出的数的最大公约数的规 ...

  4. 洛谷 P1036 选数

    P1036 选数 题目描述 已知 n 个整数 x1,x2,-,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别 ...

  5. 【洛谷】选数---深度优先搜索+单调不降去重

    题目描述 传送门:https://www.luogu.com.cn/problem/P1036 已知n个整数x1,x2-xn,以及一个整数k(k<n).从n个数字中任选k个数字相加,可分别得到一 ...

  6. 【dfs】P1036 选数

    题目链接:https://www.luogu.com.cn/problem/P1036 考点:素数.dfs.组合 题意:给n个整数,从中选取k个求和,统计"和为素数"的次数. 做法 ...

  7. BZOJ 3930 Luogu P3172 选数 (莫比乌斯反演)

    BZOJ 3930 Luogu P3172 选数 (莫比乌斯反演) 手动博客搬家:本文发表于20180310 11:46:11, 原地址https://blog.csdn.net/suncongbo/ ...

  8. 1693: 选数(DFS)

    1693: 选数 时间限制: 1 Sec 内存限制: 125 MB 题目描述 已知n个整数 x1,x2,-,xn,以及一个整数 k(k<n).从n个整数中任选k个整数相加,可分别得到一系列的和. ...

  9. [CQOI2015]选数(杜教筛)

    [CQOI2015]选数 推式子 根据题意可写出式子: ∑a1=LH∑a2=LH⋯∑an=LH[gcd(a1,a2-an)=k]∑a1=⌈Lk⌉⌊Hk⌋∑a2=⌈Lk⌉⌊Hk⌋⋯∑an=⌈Lk⌉⌊Hk ...

  10. 【BZOJ3930】选数(莫比乌斯反演倍数形式,杜教筛)

    [BZOJ3930]选数 https://www.cnblogs.com/cjyyb/p/8303813.html

最新文章

  1. mysql如何避免特殊字符查询_如何避免MySQL中的特殊字符?
  2. 《Ansible权威指南 》一 第一篇 Part 1 基础入门篇
  3. 【剑指offer-Java版】45圆圈中最后剩下的数字
  4. php开发支持的文件类型整理
  5. 中国移动互联网2018年度报告:八大关键词总结与十大趋势
  6. 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制
  7. 3-2Tensor的基本定义
  8. centos 文件夹网络连接_CentOS的网络配置的命令详解
  9. Redis教程:数据库
  10. java三色球问题_2020100期专业玩彩双色球走势分析
  11. 苹果Mac图片墙制作软件:FigrCollage
  12. 精心整理了7种常用数据分析方法(建议收藏)
  13. GitHub上的那些LGTM和WIP代表什么
  14. 【JavaWeb】石家庄地铁搭乘系统——第二版
  15. LwIP+ STM32+HTTP例程参考
  16. python判断一个字符串在数组中的位置
  17. 高德地图的基础使用(二)定位蓝点
  18. Win8系统mscomctl.ocx缺失的解决方法 run-time error 339
  19. 我家的三个犹太小富豪
  20. 为什么我选择离开工作9年的腾讯?

热门文章

  1. linux文件误删恢复解决方案
  2. 腾讯云短信服务错误码列表
  3. c++ ends理解
  4. “让我帮你百度一下”源码
  5. Jexi设计 (1) Lexi研究
  6. 构建基于 MCU 安全物联网系统
  7. JAVA根据年月查询当月的天数
  8. 【JavaScript】新浪微博如何快速批量取消关注?
  9. T2695 桶哥的问题——送桶 题解
  10. 【基础知识】9、加州房价预测