[luogu6702]Path
维护每一个点到根路径的异或和(记作$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的更多相关文章
- NodeJs之Path
Path模块 NodeJs提供的Path模块,使得我们可以对文件路径进行简单的操作. API var path = require('path'); var path_str = '\\Users\\ ...
- 【原】实时渲染中常用的几种Rendering Path
[原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...
- Node.js:path、url、querystring模块
Path模块 该模块提供了对文件或目录路径处理的方法,使用require('path')引用. 1.获取文件路径最后部分basename 使用basename(path[,ext])方法来获取路径的最 ...
- VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%
1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...
- 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 ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Thinking in Unity3D:渲染管线中的Rendering Path
关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的 ...
- node之path模块
node之path模块 原文链接 //引用该模块 var path = require("path"); 1.路径解析,得到规范化的路径格式 对window系统,目录分隔为'', ...
- Linux系统修改PATH环境变量方法
在Linux安装一些软件通常要添加路径环境变量PATH.PATH环境变量通俗的讲就是把程序的路径"备案"到系统中,这样执行这些程序时就不需要输入完整路径,直接在bash输入程序名就 ...
随机推荐
- Linux从头学15:【页目录和页表】-理论 + 实例 + 图文的最完全、最接地气详解
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- 把之前CompletableFuture留下的坑给填上。
你好呀,我是歪歪. 填个坑吧,把之前一直欠着的 CompletableFuture 给写了,因为后台已经收到过好几次催更的留言了. 这玩意我在之前写的这篇文章中提到过:<面试官问我知不知道异步编 ...
- bzoj4712 洪水(动态dp)
看起来很模板的一个题啊 qwq 但是我还是wei 题目要求的是一个把根节点和所有叶子断开连接的最小花费. 还是想一个比较\(naive\)的做法 我们令\(dp1[i]\)表示,在\(i\)的子树内, ...
- Dapr + .NET Core实战(十四)虚拟机集群部署 mDNS + Consul
前面我们说了在单机模式下和K8S集群下的Dapr实战,这次我们来看看如何在不使用K8S的情况下,在一个传统的虚拟机集群里来部署Dapr. 1.环境准备 我们准备两台centos7虚拟机 Dapr1:1 ...
- WSL (Windows Subsystem for Linux)
WSL (Windows Subsystem for Linux) :适用于 Linux 的 Windows 子系统. References Install WSL with a single com ...
- Golang通脉之面向对象
面向对象的三大特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不同实现方式 Go并不是一个纯 ...
- Java:ThreadLocal小记
Java:ThreadLocal小记 说明:这是看了 bilibili 上 黑马程序员 的课程 java基础教程由浅入深全面解析threadlocal 后做的笔记 内容 ThreadLocal 介绍 ...
- Linux中检查字符串是否为合法IP地址的shell脚本
#!/bin/bash #判断IP地址是否为有效IP CHKECK_IP () { CHECK_STEP1=`echo $1 | awk -F"." '{print NF}'` i ...
- logstash multi pipeline的使用
logstash multi pipeline的使用 一.背景 二.解决方案 1.方案一: 2.方案二: 3.方案三: 三.实现步骤 1.编写 pipeline 文件 1.从文件收集,输出到控制台 2 ...
- 梦开始的地方(Noip模拟3) 2021.5.24
T1 景区路线规划(期望dp/记忆化搜索) 一看题目发现肯定是概率期望题,再仔细想想这三天做的题,就知道是个期望dp. 考试思路(错): 因为聪聪与可可的10分打法根深蒂固,导致在考试时想到了用深搜( ...