[关闭]
@ysner 2018-08-04T01:02:10.000000Z 字数 1746 阅读 2127

最大异或和

可持久化Trie


题面

给定一个初始长度为的非负整数序列
个操作,操作分为两种:

解析

维护区间最大异或和当然要召唤可持久化树啦。
它的功能是,在完成建树后,能在给定一段区间和一个数的情况下得出它们异或得到的最大值

具体建立方法有点像把树和主席树结合起来。
插入一个数(新建一棵树),枚举到某一位时,若这个数这一位是,则只用递归处理子树,子树可以使用前面已有的对应子树。
对于询问,递归时若这一位为,则把树和树对应子树(能贡献答案的)大小作差,若差为,说明区间中不存在该位为的数,答案该位为。依此类推。
(其实看代码最清楚)

至于这个奇怪的询问方式,设异或前缀和为,则询问可视为

注意数组等数组大小要开到左右。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<vector>
  8. #define re register
  9. #define il inline
  10. #define ll long long
  11. #define max(a,b) ((a)>(b)?(a):(b))
  12. #define min(a,b) ((a)<(b)?(a):(b))
  13. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  14. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  15. using namespace std;
  16. const int mod=1e9+7,N=3e7+100;
  17. int n,m,tot,sum[N],t[N][2],rt[N],tim;
  18. il ll gi()
  19. {
  20. re ll x=0,t=1;
  21. re char ch=getchar();
  22. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  23. if(ch=='-') t=-1,ch=getchar();
  24. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  25. return x*t;
  26. }
  27. il void Build(re int x,re int &y,re int w,re int d)
  28. {
  29. sum[y=++tim]=sum[x]+1;
  30. if(d<0) return;
  31. re int tmp=(w>>d)&1;
  32. t[y][tmp^1]=t[x][tmp^1];
  33. Build(t[x][tmp],t[y][tmp],w,d-1);
  34. }
  35. il int Query(re int x,re int y,re int w,re int d)
  36. {
  37. if(d<0) return 0;
  38. re int tmp=(w>>d)&1,p=sum[t[y][tmp^1]]-sum[t[x][tmp^1]];
  39. if(p>0) return (1<<d)+Query(t[x][tmp^1],t[y][tmp^1],w,d-1);
  40. else return Query(t[x][tmp],t[y][tmp],w,d-1);
  41. }
  42. int main()
  43. {
  44. n=gi();m=gi();
  45. Build(rt[0],rt[1],0,25);++n;
  46. fp(i,2,n)
  47. {
  48. re int x=gi();tot^=x;
  49. Build(rt[i-1],rt[i],tot,25);
  50. }
  51. while(m--)
  52. {
  53. re char s[5];scanf("%s",s);
  54. if(s[0]=='A')
  55. {
  56. re int x=gi();tot^=x;
  57. Build(rt[n],rt[n+1],tot,25);++n;
  58. }
  59. else
  60. {
  61. re int l=gi(),r=gi(),x=gi();
  62. printf("%d\n",Query(rt[l-1],rt[r],tot^x,25));
  63. }
  64. }
  65. return 0;
  66. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注