维护每一个点到根路径的异或和(记作$d_{k}$),根据异或自反性,$(x,y)$的异或和即$d_{x}\oplus d_{y}$

考虑两条路径的lca,选择其中深度较大的点,另一条路径必然在其子树外,枚举这个点,分别统计子树内外异或和最大的路径

对于子树内,用启发式合并trie树,在合并时顺便统计出答案(枚举较小的一棵trie树中的点,在另一颗trie树中查询),时间复杂度为$o(n\log_{2}n\log_{2}w)$

对于子树外,任选一条全局异或和最大的路径$(p,q)$,然后将其以$p$为根建树(子树内也需要以$p$为根考虑)

将所有点分为两类:1.子树内不含有$q$;2.子树内含有$q$,对于前者必然选择$(p,q)$这条路径,否则也就是从$p$递归到$q$为止的时候

此时,暴力合并子树外的节点(即父亲子树外的节点与父亲子树内除自己外的节点),不难发现每一个节点至多合并一次,暴力合并即可做到$o(n\log_{2}w)$

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 30005
4 int E,n,x,y,z,mx,now_mx,ans,head[N],d[N],vis[N],f[N];
5 struct ji{
6 int nex,to,len;
7 }edge[N<<1];
8 struct trie{
9 int V;
10 vector<int>v,ch[2];
11 void New(){
12 ch[0].push_back(-1);
13 ch[1].push_back(-1);
14 V++;
15 }
16 void init(){
17 V=0;
18 v.clear(),ch[0].clear(),ch[1].clear();
19 New();
20 }
21 void add(int x){
22 v.push_back(x);
23 int k=0;
24 for(int i=29;i>=0;i--){
25 int p=((x&(1<<i))>0);
26 if (ch[p][k]<0){
27 ch[p][k]=V;
28 New();
29 assert(ch[p][k]>=0);
30 }
31 k=ch[p][k];
32 }
33 }
34 int query(int x){
35 if (!v.size())return 0;
36 int k=0,ans=0;
37 for(int i=29;i>=0;i--){
38 int p=((x&(1<<i))==0);
39 if (ch[p][k]<0)p^=1;
40 else ans+=(1<<i);
41 k=ch[p][k];
42 }
43 return ans;
44 }
45 int merge(int x){
46 add(x);
47 return query(x);
48 }
49 }T[N];
50 int find(int k){
51 if (k==f[k])return k;
52 return f[k]=find(f[k]);
53 }
54 int merge(int x,int y){
55 x=find(x),y=find(y);
56 assert(x!=y);
57 if (T[x].v.size()<T[y].v.size())swap(x,y);
58 f[y]=x;
59 int ans=0;
60 for(int i=0;i<T[y].v.size();i++)ans=max(ans,T[x].merge(T[y].v[i]));
61 T[y].init();
62 return ans;
63 }
64 void add(int x,int y,int z){
65 edge[E].nex=head[x];
66 edge[E].to=y;
67 edge[E].len=z;
68 head[x]=E++;
69 }
70 void dfs(int k,int fa,int s){
71 d[k]=s;
72 f[k]=fa;
73 for(int i=head[k];i!=-1;i=edge[i].nex)
74 if (edge[i].to!=fa)dfs(edge[i].to,k,s^edge[i].len);
75 }
76 void tot(int k,int fa){
77 now_mx=max(now_mx,T[0].merge(d[k]));
78 for(int i=head[k];i!=-1;i=edge[i].nex)
79 if (edge[i].to!=fa)tot(edge[i].to,k);
80 }
81 void calc(int k,int fa){
82 int si=T[k].merge(d[k]),so=mx;
83 if (vis[k]){
84 so=now_mx;
85 now_mx=max(now_mx,T[0].merge(d[k]));
86 for(int i=head[k];i!=-1;i=edge[i].nex)
87 if (!vis[edge[i].to])tot(edge[i].to,k);
88 }
89 for(int i=head[k];i!=-1;i=edge[i].nex)
90 if (edge[i].to!=fa){
91 calc(edge[i].to,k);
92 si=max(si,merge(k,edge[i].to));
93 }
94 if (fa)ans=max(ans,si+so);
95 }
96 int main(){
97 scanf("%d",&n);
98 memset(head,-1,sizeof(head));
99 for(int i=1;i<n;i++){
100 scanf("%d%d%d",&x,&y,&z);
101 add(x,y,z);
102 add(y,x,z);
103 }
104 dfs(1,0,0);
105 T[0].init();
106 for(int i=1;i<=n;i++)mx=max(mx,T[0].merge(d[i]));
107 for(int i=1;i<=n;i++)
108 if (T[0].query(d[i])==mx){
109 x=i;
110 break;
111 }
112 for(int i=1;i<=n;i++)
113 if ((d[x]^d[i])==mx){
114 y=i;
115 break;
116 }
117 dfs(x,0,0);
118 while (y){
119 vis[y]=1;
120 y=f[y];
121 }
122 for(int i=0;i<=n;i++)T[i].init();
123 for(int i=1;i<=n;i++)f[i]=i;
124 calc(x,0);
125 printf("%d",ans);
126 }

[luogu6702]Path的更多相关文章

  1. NodeJs之Path

    Path模块 NodeJs提供的Path模块,使得我们可以对文件路径进行简单的操作. API var path = require('path'); var path_str = '\\Users\\ ...

  2. 【原】实时渲染中常用的几种Rendering Path

    [原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...

  3. Node.js:path、url、querystring模块

    Path模块 该模块提供了对文件或目录路径处理的方法,使用require('path')引用. 1.获取文件路径最后部分basename 使用basename(path[,ext])方法来获取路径的最 ...

  4. VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%

    1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...

  5. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  6. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

  7. Thinking in Unity3D:渲染管线中的Rendering Path

      关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的 ...

  8. node之path模块

    node之path模块 原文链接 //引用该模块 var path = require("path"); 1.路径解析,得到规范化的路径格式 对window系统,目录分隔为'', ...

  9. Linux系统修改PATH环境变量方法

    在Linux安装一些软件通常要添加路径环境变量PATH.PATH环境变量通俗的讲就是把程序的路径"备案"到系统中,这样执行这些程序时就不需要输入完整路径,直接在bash输入程序名就 ...

随机推荐

  1. Spring Bean装配笔记

    Spring Bean装配笔记 Spring中的Bean是一个很重要的概念.Spring作为一个Bean容器,它可以管理对象和对象之间的依赖关系,我们不需要自己建立对象,把这部分工作全部转交给容器完成 ...

  2. 题解 「BJOI2018 治疗之雨」

    题目传送门 题目大意 有一个初始为 \(p\) 的数,每次操作分为以下两个: 有 \(\frac{1}{m+1}\) 的概率$+1,但是中途 \(p\) 的最大值只能为 \(n\)$ 有 \(k\) ...

  3. IEEE754浮点数的转换

    将十进制数转换为单精度浮点数 如何将十进制数转换为单精度浮点数参考 首先要知道 IEEE浮点标准:V=(-1)^s * M * 2^E 1.符号(sign)s决定这个数是负数(s=1)还是正数,0(s ...

  4. 谈谈BEM规范(含代码)

    css规范之BEM规范 前言 引用一句经典名言在编程的世界里其中一件最难的事情就是命名,不管是设计到编程语言还是标记语言都会有命名的需求.今天聊的就是关于css的命名规范的发展过程以及演变. 命名的发 ...

  5. Beta阶段第五次会议

    Beta阶段第五次会议 时间:2020.5.21 完成工作 姓名 工作 难度 完成度 ltx 1.对小程序进行修改和美化新增页面(新增60行) 中 85% xyq 1.编写技术博客 中 85% xtl ...

  6. Elasticsearch核心技术(三):Mapping设置

    本文从Mapping简介.Dynamic Mapping.自定义Mapping和Mapping常用参数说明4个部分介绍Elasticsearch如何设置Mapping. 3.1 Mapping简介 3 ...

  7. Spring的Ioc与DI

    一.前言 Spring框架的核心基于控制反转的原理. IoC是一种将组件依赖关系的创建和管理外部化的技术. 考虑一个示例,其中Foo类依赖于Bar类的实例来执行某种处理. 传统上,Foo使用new运算 ...

  8. popStar手机游戏机机对战程序

    DFS算,五分钟如果答案没有更新,那个解一般来说就很优了. #include <cstdio> #include <iostream> #include <string. ...

  9. 近期业务大量突增微服务性能优化总结-3.针对 x86 云环境改进异步日志等待策略

    最近,业务增长的很迅猛,对于我们后台这块也是一个不小的挑战,这次遇到的核心业务接口的性能瓶颈,并不是单独的一个问题导致的,而是几个问题揉在一起:我们解决一个之后,发上线,之后发现还有另一个的性能瓶颈问 ...

  10. 关于linux7.x系列下的 systemd 的理解

    历史上Linux的启动一直采用init进程,下面的命令用来启动服务. $ sudo /etc/init.d/apache2 start #或者 $ service apache2 start 这种方法 ...