题目链接:http://poj.org/problem?id=3764

分析:好题!武森09年的论文中有道题CowXor,求的是线性结构上的,连续序列的异或最大值,用的办法是先预处理出前n项的异或值,然后在这些值中找出两个值的异或值最大。是基于这样的一个原理,相同段的异或值为0。这题在树中找两个节点,两个节点间有唯一路径(因为是树),把路径不断做异或,异或完后求最大的。数据是10万,O(n2)算法超时。我们知道异或有这样的性质:a^b = (a^c)^(b^c),这样就可以考虑找出a与b公共的c,实际上就是求出从根节点到每个节点的异或值,这样任意两个点做异或,即是他们之间的异或路径(相同部分异或抵消了)。实际上又回到了n(n>100000)个数中找两个值的异或值最大。n^2遍历肯定不行了,这里我们用字典树+贪心优化。即建立一棵trie树每层只有0和1;然后将每个点到达根节点的异或和(这里dfs就行)insert进trie树,然后对于每个点从高位往低位一层层在字典树中尽量找与它相异的值(相异为1嘛,且任意每层取一个数形成的二进制数都是之前插进去的),这样找得下来的值至少大于原值,必定能找出最优值,复杂度(n*30)。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <queue>
  7. #include <cstdlib>
  8. #include <vector>
  9. #include <set>
  10. #include <map>
  11. #define LL long long
  12. #define inf 1<<30
  13. #define mod 1000000007
  14. #define N 100010
  15. using namespace std;
  16. struct edge
  17. {
  18. int v,w,next;
  19. edge(){}
  20. edge(int v,int w,int next):v(v),w(w),next(next){}
  21. }e[N<<];
  22. int head[N],vis[N],nor[N],tot;
  23. void addedge(int u,int v,int w)
  24. {
  25. e[tot]=edge(v,w,head[u]);
  26. head[u]=tot++;
  27. }
  28. void dfs(int u,int w)
  29. {
  30. vis[u]=;nor[u]=w;
  31. for(int i=head[u];~i;i=e[i].next)
  32. {
  33. int v=e[i].v;
  34. if(vis[v])continue;
  35. dfs(v,e[i].w^w);
  36. }
  37. }
  38. struct Trie
  39. {
  40. int next[N<<][];
  41. int root,L;
  42. int newnode()
  43. {
  44. next[L][]=next[L][]=-;
  45. return L++;
  46. }
  47. void init()
  48. {
  49. L=;
  50. root=newnode();
  51. }
  52. void insert(int x)
  53. {
  54. int now=root;
  55. for(int i=;i>=;i--)
  56. {
  57. int num=(<<i)&x?:;
  58. if(next[now][num]==-)
  59. next[now][num]=newnode();
  60. now=next[now][num];
  61. }
  62. }
  63. int find(int x)
  64. {
  65. int now=root,res=;
  66. for(int i=;i>=;i--)//从二进制的第31位到第1位查找最大异或值
  67. {
  68. int num=(<<i)&x?:;//获取num的二进制数的第i+1位上的数字的非
  69. if(next[now][num]!=-)//如果字典树有要查找的数即有相异的数
  70. {
  71. res|=<<i;//加上该位的权值
  72. now=next[now][num];//进入下一层
  73. }
  74. else now=next[now][!num];//如果没有,则按num当前位上的数字进入下一层查找
  75. }
  76. return res;
  77. }
  78. }trie;
  79. int main()
  80. {
  81. int n,u,v,w;
  82. while(scanf("%d",&n)>)
  83. {
  84. memset(vis,,sizeof(vis));
  85. memset(head,-,sizeof(head));
  86. tot=;trie.init();
  87. for(int i=;i<n;i++)
  88. {
  89. scanf("%d%d%d",&u,&v,&w);
  90. addedge(u,v,w);
  91. addedge(v,u,w);
  92. }
  93. dfs(,);
  94. int ans=,mx;
  95. for(int i=;i<n;i++)
  96. {
  97. trie.insert(nor[i]);
  98. mx=trie.find(nor[i]);
  99. ans=max(ans,mx);
  100. }
  101. printf("%d\n",ans);
  102. }
  103. }

poj3764(dfs+Trie树+贪心)的更多相关文章

  1. 【BZOJ3261】最大异或和 Trie树+贪心

    [BZOJ3261]最大异或和 Description 给定一个非负整数序列 {a},初始长度为 N.       有   M个操作,有以下两种操作类型:1 .A x:添加操作,表示在序列末尾添加一个 ...

  2. [SCOI2016] 背单词 (Trie 树,贪心)

    题目链接 大致题意 给你 \(n\) 个字符串, 要求你给出最小的代价. 对于每个字符串: 1.如果它的后缀在它之后,那么代价为 \(n^2\). 2.如果一个字符串没有后缀,那么代价为 \(x\), ...

  3. 51nod 1526 分配笔名(Trie树+贪心)

    建出Trie树然后求出一个点子树中有多少笔名和真名.然后贪心匹配即可. #include<iostream> #include<cstring> #include<cst ...

  4. BZOJ4567 [Scoi2016]背单词 【trie树 + 贪心】

    题目链接 BZOJ4567 题解 题意真是鬼畜= = 意思就是说我们应先将一个串的所有后缀都插入之后再插入这个串,产生代价为其到上一个后缀的距离 我们翻转一下串,转化为前缀,就可以建\(trie\)树 ...

  5. 【bzoj3261】【最大异或和】可持久化trie树+贪心

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61705397 Description 给定一个非 ...

  6. POJ 3764 DFS+trie树

    题意: 给你一棵树,求树中最长的xor路径.(n<=100000) 思路: 首先我们知道 A xor B =(A xor C) xor (B xor C) 我们可以随便选一个点DFS 顺便做出与 ...

  7. [CSP-S模拟测试]:big(Trie树+贪心)

    题目描述 你需要在$[0,2^n)$中选一个整数$x$,接着把$x$依次异或$m$个整数$a_1~a_m$.在你选出$x$后,你的对手需要选择恰好一个时刻(刚选完数时.异或一些数后或是最后),将$x$ ...

  8. 【BZOJ4260】Codechef REBXOR Trie树+贪心

    [BZOJ4260]Codechef REBXOR Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. Output ...

  9. 【HDU6687】Rikka with Stable Marriage(Trie树 贪心)

    题目链接 大意 给定\(A,B\)两个数组,让他们进行匹配. 我们称\(A_i\)与\(B_j\)的匹配是稳定的,当且仅当目前所剩元素不存在\(A_x\)或\(B_y\)使得 \(A_i\oplus ...

随机推荐

  1. 关于SQL中Between语句查询日期的问题

      在CSDN找到了相同的问题描述和解决方法: 问题: 我的表某个字段是Datetime型 以" YYYY-MM-DD 00:00:00" 存放 如 A 2009-01-22 21 ...

  2. webform中几个常用的控件

    一,简单控件 1,Lable——标签:在网页中呈现出来的时候会变成span标签 属性:Text——标签上的文字  BackColor,ForeColor——背景色,前景色 Font——字体 Bold- ...

  3. Fibinary Numbers

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30506#problem/V 题意:从右向左,每一个位数,分别表示一个fibonacci数 ...

  4. MFC 关于对话框的注意点

    1.对于模态对话框而言,单击确定以后对话框窗口对象即被销毁了,而对于非模态对话框来说,对话框的对象并未销毁而是隐藏起来(EndDialog函数),因此对于非模态对话框,必须重写OnOK这个虚函数,并在 ...

  5. 基于TCP/IP协议的C++网络编程(API函数版)

    源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...

  6. 微信公 众平台开发,用于个人技术交流,有兴趣的加QQ群432921500

    微信公 众平台开发,用于个人技术交流,有兴趣的加QQ群432921500

  7. Koa -- 基于 Node.js 平台的下一代 web 开发框架

    http://koa.bootcss.com/ 多研究点 react 和 nodejs 这个是未来

  8. JSP的学习(1)——基本知识与底层原理

    通过之前的学习,我们已经对Servlet有所了解,现在我们先来学习JSP,当能使用JSP进行友好的页面显示之后,再回去学习Servlet的其他高级特性会将整个学习很好的融入进来. JSP,即Java ...

  9. DAG上的动态规划

    嵌套矩形问题(最长路及其字典序)有n个举行,选出尽量多的矩阵排成一排,使得除了最后一个之外,每一个矩形可以嵌套在下一个矩形内,并且打印 #include <iostream> #inclu ...

  10. 让XP系统支持GPT硬盘

    转自 http://article.pchome.net/content-1324506-all.html 1XP系统还不过时 教你完美征服3TB硬盘回顶部 原作者:沈洁 随着高清1080p片源的普及 ...