Description:

现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值v

​现在有Q次操作,操作如下:

1.1\ x\ y\ :查询节点x的子树中与y异或结果的最大值

2.2\ x\ y\ z\ :查询路径x到y上点与z异或结果最大值

Hint:

\(n,q<=10^5\)

Solution:

水题,按dfs序建主席树解决询问1,树上主席树解决询问2

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mxm=1e5+5,mxn=5e6+5;
  4. int n,m,cnt,val[mxm],hd[mxm],sz[mxm],id[mxm],dep[mxm],f[mxm][18];
  5. struct ed {
  6. int to,nxt;
  7. }t[mxm<<1];
  8. inline void add(int u,int v) {
  9. t[++cnt]=(ed) {v,hd[u]}, hd[u]=cnt;
  10. }
  11. struct Trie {
  12. int ch[mxn][2],rt[mxn],sum[mxn],tot,dfn;
  13. void dfs1(int u,int fa) {
  14. sz[u]=1; id[u]=++dfn;
  15. ins(rt[id[u]-1],rt[id[u]],30,val[u]);
  16. for(int i=hd[u];i;i=t[i].nxt) {
  17. int v=t[i].to;
  18. if(v==fa) continue ;
  19. dfs1(v,u); sz[u]+=sz[v];
  20. }
  21. }
  22. void dfs2(int u,int fa) {
  23. f[u][0]=fa; dep[u]=dep[fa]+1;
  24. ins(rt[fa],rt[u],30,val[u]);
  25. for(int i=hd[u];i;i=t[i].nxt) {
  26. int v=t[i].to;
  27. if(v==fa) continue ;
  28. dfs2(v,u);
  29. }
  30. }
  31. int LCA(int x,int y) {
  32. if(dep[x]<dep[y]) swap(x,y);
  33. for(int i=17;i>=0;--i)
  34. if(dep[f[x][i]]>=dep[y])
  35. x=f[x][i];
  36. if(x==y) return x;
  37. for(int i=17;i>=0;--i)
  38. if(f[x][i]!=f[y][i])
  39. x=f[x][i],y=f[y][i];
  40. return f[x][0];
  41. }
  42. void init() {
  43. for(int j=1;j<=17;++j)
  44. for(int i=1;i<=n;++i)
  45. f[i][j]=f[f[i][j-1]][j-1];
  46. }
  47. void ins(int pre,int& p,int k,int x) {
  48. p=++tot; sum[p]=sum[pre]+1; if(k<0) return ;
  49. int tp=x>>k&1; ch[p][tp^1]=ch[pre][tp^1];
  50. ins(ch[pre][tp],ch[p][tp],k-1,x);
  51. };
  52. int query1(int pre,int p,int k,int x) {
  53. if(k<0) return 0; int tp=x>>k&1;
  54. int is=sum[ch[p][tp^1]]-sum[ch[pre][tp^1]];
  55. if(is) return (1<<k)+query1(ch[pre][tp^1],ch[p][tp^1],k-1,x);
  56. else return query1(ch[pre][tp],ch[p][tp],k-1,x);
  57. };
  58. int query2(int las1,int las2,int p1,int p2,int k,int x) {
  59. if(k<0) return 0; int tp=x>>k&1;
  60. int is=sum[ch[p1][tp^1]]+sum[ch[p2][tp^1]]-sum[ch[las1][tp^1]]-sum[ch[las2][tp^1]];
  61. if(is) return (1<<k)+query2(ch[las1][tp^1],ch[las2][tp^1],ch[p1][tp^1],ch[p2][tp^1],k-1,x);
  62. else return query2(ch[las1][tp],ch[las2][tp],ch[p1][tp],ch[p2][tp],k-1,x);
  63. }
  64. }T1,T2;
  65. int main()
  66. {
  67. scanf("%d%d",&n,&m); int opt,x,y,z,u,v;
  68. for(int i=1;i<=n;++i) scanf("%d",&val[i]);
  69. for(int i=1;i<n;++i) {
  70. scanf("%d%d",&u,&v);
  71. add(u,v); add(v,u);
  72. }
  73. T1.dfs1(1,0),T2.dfs2(1,0),T2.init();
  74. for(int i=1;i<=m;++i) {
  75. scanf("%d",&opt);
  76. if(opt==1) {
  77. scanf("%d%d",&x,&y);
  78. printf("%d\n",T1.query1(T1.rt[id[x]-1],T1.rt[id[x]+sz[x]-1],30,y));
  79. }
  80. else {
  81. scanf("%d%d%d",&x,&y,&z); int lca=T2.LCA(x,y);
  82. printf("%d\n",T2.query2(T2.rt[f[lca][0]],T2.rt[lca],T2.rt[x],T2.rt[y],30,z));
  83. }
  84. }
  85. return 0;
  86. }

[TJOI2018]异或的更多相关文章

  1. 【BZOJ5338】[TJOI2018]异或(主席树)

    [BZOJ5338][TJOI2018]异或(主席树) 题面 洛谷 题解 很明显的是\(Trie\)树上暴力判断答案 因为要支持区间,用主席树的结构存\(Trie\)树就好了 #include< ...

  2. 洛谷 P4592 [TJOI2018]异或 解题报告

    P4592 [TJOI2018]异或 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1 x y:查 ...

  3. 洛谷 P4592: bzoj 5338: [TJOI2018]异或

    题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...

  4. [洛谷P4592][TJOI2018]异或

    题目大意:有一棵$n$个点的树,第$i$个点权值为$w_i$,有两种操作: $1\;x\;y:$询问节点$x$的子树中与$y$异或结果的最大值 $2\;x\;y\;z:$询问路径$x$到$y$上点与$ ...

  5. BZOJ5338:[TJOI2018]异或——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5338 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操 ...

  6. 可持久化01Trie树+LCA【p4592】[TJOI2018]异或

    Description 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1\(\;x\;y\):查询节点\(x ...

  7. P4592 [TJOI2018]异或 (可持久化Trie)

    [题目链接] https://www.luogu.org/problemnew/show/P4592 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\ ...

  8. 洛谷P4592 [TJOI2018]异或(可持久化01Trie)

    题意 题目链接 可持久化01Trie板子题 对于两个操作分别开就行了 #include<bits/stdc++.h> using namespace std; const int MAXN ...

  9. P4592 [TJOI2018]异或

    吐槽 睡起来写道模板清醒一下 貌似有两个log的树剖写法,还有一个log的Trie树的差分做法(类似于count on a tree),然后一个log的要把两个询问分开写,一个dfs序一个差分,然后我 ...

随机推荐

  1. 字符驱动之二操作方法(struct file_operations)【转】

    转自:http://blog.chinaunix.net/uid-26837113-id-3157515.html 从上一篇我们看到了字符驱动的三个重要结构,那我现在跟大家详细的说说 struct f ...

  2. cocos2d-x播放视频的处理

    cocos2d-x是支持直接播放视频的,用的是Native端的播放器,视频的默认层级是在cocos的层级之上,如果是想让视频上面有cocos的控件,只能将视频的UI层级放在最下面,这个方法网上已经有比 ...

  3. 企业内部在centos7.2系统中必杀技NTP时间服务器及内网服务器时间同步(windows和linux客户端同步)

    网络时间协议NTP(Network Time Protocol)是用于互联网中时间同步的标准互联网协议.NTP的用途是把计算机的时间同步到某些时间标准.目前采用的时间标准是世界协调时UTC(Unive ...

  4. PL/SQL第四章 where子语句

    -- 学习where语句 -- 1.学会where子句中使用常规比较符 -- 常规比较操作符:=,<>(不等于),!=,>=,<=,>,< -- 当区分大小写时,可 ...

  5. 为什么js中0.1+0.2不等于0.3,怎样处理使之相等?(转载)

    为什么js中0.1+0.2不等于0.3,怎样处理使之相等? console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个 ...

  6. php中类继承和接口继承的对比

    PHP类继承: 1.PHP类不支持多继承,也就是子类只能继承一个父类,但是支持多层次继承,比如: class frist{ public function __construct(){ echo &q ...

  7. 使用@property - 廖雪峰的官方网站

    使用@property 阅读: 20616 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9 ...

  8. javafx的scene大小不能在控制器中设置

    做个记录,备忘 遇到一个问题,点击提交,红色标识的VBox大小不能改变.问题如图,代码如下 点击后 fxml结构简化代码: 红色框体对应vboxMax <VBox fx:id="vbo ...

  9. ERP合同列表页面自动导航(三十二)

    合同审核完成页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CRMC ...

  10. python全栈开发day36-IO多路复用

    一.复习 1.进程.线程.协程 进程:是计算机中最小的资源分配单位,数据隔离,可以利用多核,数据不安全 线程:是计算机中最小的CPU调度单位,数据共享,GIL,数据不安全 协程:是线程的一部分,是由用 ...