fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int N = 6e5 + 10;
  6.  
  7. int s[N]; // s[i]代表a[1]^a[2]^...^a[i],s[0]=0
  8. int n, m;
  9. int len = 23; // 0<=a[i]<=1e7,最多23位,所以最多23*N个结点
  10. int ver[25 * N], idx; // ver代表每个结点所属版本,idx代表树中每个结点的编号
  11. int son[25 * N][2]; //每个结点的孩子的编号
  12. int root[N]; // s[0~N]->每插入一个算一个版本,有版本0~N,root代表每个版本的根
  13.  
  14. // 三个参数代表,当前版本的根now,前一个版本的根pre,当前版本号i
  15. void insert(int now, int pre, int i) {
  16. ver[now] = i;
  17. for (int k = len; k >= 0; k--) {
  18. int u = s[i] >> k & 1;
  19. son[now][!u] = son[pre][!u];
  20. son[now][u] = ++idx;
  21. now = son[now][u], pre = son[pre][u];
  22. ver[now] = i;
  23. }
  24. }
  25. //在版本[l-1,r-1]中查找最大值,三个参数分别为root[r-1],l-1,定值s[n]^x
  26. int query(int R, int L, int v) {
  27. int res = 0;
  28. for (int k = len; k >= 0; k--) {
  29. int u = v >> k & 1;
  30. //如果可以走反方向
  31. if (ver[son[R][!u]] >= L) {
  32. res |= 1 << k;
  33. R = son[R][!u];
  34. } else
  35. R = son[R][u];
  36. }
  37. return res;
  38. }
  39.  
  40. int main() {
  41. cin >> n >> m;
  42. ver[0] = -1; //结点编号为0代表空结点
  43. root[0] = ++idx;
  44. //插入s[0]产生版本0
  45. insert(root[0], 0, 0);
  46. for (int i = 1; i <= n; i++) {
  47. cin >> s[i];
  48. s[i] ^= s[i - 1];
  49. root[i] = ++idx;
  50. //每插入一个s[i]产生一个版本
  51. insert(root[i], root[i - 1], i);
  52. }
  53. // m次询问
  54. for (int i = 1; i <= m; i++) {
  55. char op;
  56. cin >> op;
  57. if (op == 'A') {
  58. n++;
  59. cin >> s[n];
  60. s[n] ^= s[n - 1];
  61. root[n] = ++idx;
  62. insert(root[n], root[n - 1], n);
  63. } else {
  64. int l, r, x;
  65. cin >> l >> r >> x;
  66. cout << query(root[r - 1], l - 1, x ^ s[n]) << endl;
  67. }
  68. }
  69. return 0;
  70. }
Success #stdin #stdout 0.01s 5272KB
stdin
Standard input is empty
stdout
Standard output is empty