暴力求解(40%):

  1. #include<iostream>
  2. using namespace std;
  3. typedef long long LL;
  4. const int N = 1e5 + 10;
  5. LL a[N] , s[N] , ans = 0 , sum = 0;
  6. int n;
  7. int main()
  8. {
  9. cin>>n;
  10. for(int i = 1;i <= n;i ++) cin>>a[i];
  11. for(int i = 1;i <= n;i ++) s[i] = s[i-1] ^ a[i],cout<<s[i]<<endl;;
  12. LL maxx , minn;
  13. maxx = minn = s[0] ^ s[1];
  14. for(int i = 1;i <= n;i ++)
  15. {
  16. for(int j = i;j <= n;j ++)
  17. {
  18. sum = s[i-1] ^ s[j];
  19. minn = min(minn , sum);
  20. maxx = max(maxx , sum);
  21. cout<<sum<<' ';
  22. }
  23. cout<<endl;
  24. }
  25. ans = maxx - minn;
  26. cout<<ans<<endl;
  27. return 0;
  28. }

时间优化

利用trie树的特性寻找异或的最大最小值:

trie树知识点:https://www.acwing.com/blog/content/15077/

一位大佬的代码思路讲解:https://www.bilibili.com/video/BV1ty421z77K/?spm_id_from=333.788&vd_source=5f7e4c928f2ae7a33f99f74c695f9806

最终代码:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std ;
  5. const int N = 1e6 + 10 ;
  6. int n , a[N] ;
  7. int son[2][N] , idx ;
  8. int mx[N] , mi[N] ;
  9. void add(int x)
  10. {
  11. int p = 0 ;
  12. for(int i = 20 ; i >= 0 ; i --)
  13. {
  14. int u = (x>>i) & 1; //判断x的第i位上是1/0
  15. if(!son[u][p]) son[u][p] = ++idx; //若节点不存在,则按照当前位置上的数是多少来构造树
  16. p = son[u][p]; //指向构造好的节点准备构造下一位
  17. }
  18. }
  19. int query_mx(int x)
  20. {//异或值最大则需要尽可能多【不相同】的位数
  21. int p = 0 , res = 0;
  22. for(int i = 20;i >= 0;i --)
  23. {
  24. int u = (x >> i) & 1;
  25. if(son[!u][p]) res |= (1 << i);
  26. else u = !u;
  27. p = son[!u][p];
  28. }
  29. return res;
  30. }
  31. int query_mi(int x)
  32. {//异或值最小则需要尽可能多【相同】的位数
  33. int p = 0 , res = 0;
  34. for(int i = 20;i >= 0;i --)
  35. {
  36. int u = (x >> i) & 1;
  37. if(!son[u][p]) //若与当前位相同的节点不存在,则最小异或
  38. {
  39. u = !u;
  40. res |= (1 << i);
  41. }
  42. p = son[u][p];
  43. }
  44. return res;
  45. }
  46. int main()
  47. {
  48. cin>>n;
  49. for(int i = 1;i <= n;i ++) cin>>a[i];
  50. mx[0] = 0 , mi[0] = 1e9;
  51. int sum = 0;
  52. add(sum);
  53. for(int i = 1;i <= n;i ++)
  54. {//寻找i左边的异或和最大值和最小值
  55. sum ^= a[i]; //前缀和
  56. mx[i] = max(mx[i-1] , query_mx(sum)); //动态规划,i左边的最大值=i-1左边的最大值(不包括i)和以i为右端点(包括i)的最大值
  57. mi[i] = min(mi[i-1] , query_mi(sum));
  58. add(sum); //构造树
  59. }
  60. memset(son , 0 , sizeof son) ;
  61. idx = 0 ; sum = 0 ;
  62. int ans = 0 , mx2 = 0 , mi2 = 2e9;
  63. add(sum) ;
  64. for(int i = n ; i ; i --)
  65. {//寻找i右边的异或和最大值和最小值(倒序)
  66. sum ^= a[i] ;
  67. mx2 = max(mx2 , query_mx(sum)) ; //同上
  68. mi2 = min(mi2 , query_mi(sum)) ;
  69. //取(ans , 右最大-左最小 , 左最大-右最小)的最大值
  70. ans = max({ans , mx[i - 1] - mi2 , mx2 - mi[i - 1]}) ;
  71. add(sum) ;
  72. }
  73. cout<<ans<<endl;
  74. return 0;
  75. }
点赞(0)
 

9.9 分

1 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论