维护每一个点到根路径的异或和(记作$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. 使用python -m pip install 和 pip install 安装包有什么区别?

    如果去看源码的话,你会发现 pip 作为执行文件的入口点是 pip._internal.main. 另一方面,pip 作为模块运行时入口是 _main.py,而该模块也只是调用 pip.interna ...

  2. Zookeeper 集群部署的那些事儿

    简介 额...., &*$% 淘气! ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务. ZooKeeper本质上是一个分布式的小文件存储系统 ...

  3. Serverless:这真的是未来吗?(二)

    原文 | https://www.pulumi.com/blog/is_serverless_the_future_part_2/ 作者 | Lee Briggs & Piers Karsen ...

  4. 从零入门 Serverless | SAE 场景下,应用流量的负载均衡及路由策略配置实践

    作者 | 落语 阿里云云原生技术团队 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 S ...

  5. JSR303数据校验

    Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理. 导入依赖: <dependency> <groupId>org ...

  6. Vim 不区分大小写

    Vim 不区分大小写 忽略:set ignorecase 恢复:set noignorecase

  7. Bootstrap响应式的导航栏

    Bootstrap 导航栏 | 菜鸟教程 <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...

  8. 【UE4 C++】UGameplayStatics 源代码

    // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...

  9. [技术博客] BeautifulSoup4分析网页

    [技术博客] BeautifulSoup4分析网页 使用BeautifulSoup4进行网页文本分析 前言 进行网络爬虫时我们需要从网页源代码中提取自己所需要的信息,分析整理后存入数据库中. 在pyt ...

  10. VUE调用子窗口弹窗或组件弹窗,关闭弹窗刷新父级页面主页面,通过this.$emit来实现

    this.$emit是父级向自己传值 第一步在父级页面创建自己页面的引用 <template> <div> <edit ref="edit" @ref ...