维护每一个点到根路径的异或和(记作$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. JVM学习笔记——类加载器与类加载过程

    类加载器与类加载过程 类加载器ClassLoader 类加载器 ClassLoader 用于把 class 文件装载进内存. 启动类加载器(Bootstrap ClassLoader): 这个类加载使 ...

  2. windows下编译caffe出现错误 C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe?

    解决方案来自http://blog.csdn.net/u012556077/article/details/50353818

  3. Knativa 基于流量的灰度发布和自动弹性实践

    作者 | 李鹏(元毅) 来源 | Serverless 公众号 一.Knative Knative 提供了基于流量的自动扩缩容能力,可以根据应用的请求量,在高峰时自动扩容实例数:当请求量减少以后,自动 ...

  4. Schematics Tools(Schematics 工具)

    Schematics工具 # Process: 创建逻辑示意图 arcpy.CreateDiagram_schematics("", "", "&qu ...

  5. UE4蓝图AI角色制作(七)之追逐玩家

    15.追逐玩家 现在我们的AI无法做出任何决策,它总是执行相同的决策.我们先把感知系统中的相关信息提供给AI,让AI知道如何做出决策,然后我们会修改行为树.我们首先需要创建新的黑板键,这样我们就能在行 ...

  6. .Net Core微信服务商二次进件

    最近商城进行微信服务商二次进件的开发,大致有几个点 一,服务商签名 二,服务商证书获取 三,图片上传 四,敏感信息加密 五,查询进件状态 除此之外,就是进件信息的拼装 电商二级商户进件申请单-状态流转 ...

  7. 【UE4】GamePlay架构

    新标签打开或者下载看大图 更新: 增加 编程子系统 Subsystem 思维导图 Character pipeline

  8. 【UE4 设计模式】单例模式 Singleton Pattern

    概述 描述 保证一个类只有一个实例 提供一个访问该实例的全局节点,可以视为一个全局变量 仅在首次请求单例对象时对其进行初始化. 套路 将默认构造函数设为私有, 防止其他对象使用单例类的 new运算符. ...

  9. Vite启动后提示Network: use `--host` to expose

    当使用 Vite 构建项目后,发现只有localhost + 端口 服务,没有 IP + 端口服务. 运行npm run dev,终端提示Vite启动后提示Network: use '--host' ...

  10. Java:并发笔记-08

    Java:并发笔记-08 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 7. 共享模型之工具-1 7.1 线程池 1. 自定义线程池 步骤1:自定义拒绝策略接 ...