【xsy1122】 路径 点分治+trie
题目大意:给你一棵n个点的树,树边上有边权,对于每一个点,你要求出经过该点的所有的路径中,路径异或和最大的值。
数据范围:$n≤10^5$,边权$≤10^9$。
我们考虑枚举每一条路径,显然这个是会T的,于是我们用点分治来实现这个过程。
对于一棵以$x$为根的子树,假设它有$k$个儿子,编号$v1....k$。
我们维护一棵$trie$树,记录所有从根到以$v1,v2.....vp$为跟的子树中的路径长度。
对于从跟到第$p+1$个儿子为跟的树中的每一条路径,我们都丢到$trie$树中查询与最大的异或值。
在查询最大值的过程中,我们维护一个$max_i$,表示从根到i的路径上的最大路径异或和。我们可以通过简单的标记上传去实现更新。
然后再将所有终点在$p+1$个子树中的路径加入到$trie$树种。
时间复杂度:$O(n\ log\ n\ log\ v)$。
#include<bits/stdc++.h>
#define M 100005
#define INF ((1<<31)-1)
using namespace std; struct edge{int u,v,next;}e[M*]={}; int head[M]={},Use=;
void add(int x,int y,int z){Use++;e[Use].u=y;e[Use].v=z;e[Use].next=head[x];head[x]=Use;} int use=;
struct trie{int a[];}a[M*]={};
void add(int x){
int now=;
for(int i=;~i;i--){
bool k=(<<i)&x;
if(a[now].a[k]) now=a[now].a[k];
else a[now].a[k]=++use,a[use].a[]=a[use].a[]=,now=use;
}
}
int query(int x){
int now=,res=;
for(int i=;~i;i--){
bool k=(<<i)&x;
if(a[now].a[k^]) now=a[now].a[k^],res+=(<<i);
else now=a[now].a[k];
}
return res;
} int siz[M]={},vis[M]={};
int minn=INF,minid=;
void dfssiz(int x,int fa){
siz[x]=;
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==)
dfssiz(e[i].u,x),siz[x]+=siz[e[i].u];
}
void dfsmax(int x,int fa,int fsiz){
int maxn=fsiz-siz[x];
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==){
dfsmax(e[i].u,x,fsiz);
maxn=max(maxn,siz[e[i].u]);
}
if(maxn<minn) minn=maxn,minid=x;
}
int makeroot(int x){
dfssiz(x,);
minn=INF; minid=;
dfsmax(x,,siz[x]);
return minid;
} int ans[M]={},now[M]={};
void upans(int x,int fa,int Val){
int hh=query(Val);
now[x]=hh;
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==){
upans(e[i].u,x,Val^e[i].v);
now[x]=max(now[x],now[e[i].u]);
}
ans[x]=max(ans[x],now[x]);
}
void addtrie(int x,int fa,int Val){
add(Val);
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==){
addtrie(e[i].u,x,Val^e[i].v);
}
} stack<int> s;
void dfs(int x){
x=makeroot(x); vis[x]=; a[].a[]=a[].a[]=; use=;
add();
for(int i=head[x];i;i=e[i].next) if(vis[e[i].u]==){
upans(e[i].u,x,e[i].v);
ans[x]=max(ans[x],now[e[i].u]);
addtrie(e[i].u,x,e[i].v);
s.push(i);
} a[].a[]=a[].a[]=; use=;
add();
while(!s.empty()){
int i=s.top(); s.pop();
upans(e[i].u,x,e[i].v);
ans[x]=max(ans[x],now[e[i].u]);
addtrie(e[i].u,x,e[i].v);
} for(int i=head[x];i;i=e[i].next) if(vis[e[i].u]==)
dfs(e[i].u);
} int main(){
int n; scanf("%d",&n);
for(int i=;i<n;i++){
int x,y,z; scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs();
for(int i=;i<=n;i++) printf("%d\n",ans[i]);
}
【xsy1122】 路径 点分治+trie的更多相关文章
- 【Tsinsen-A1486】树(王康宁) 点分治 + Trie
A1486. 树(王康宁) 时间限制:1.0s 内存限制:512.0MB 总提交次数:455 AC次数:97 平均分:52.62 查看未格式化的试题 提交 试题讨论 试题来源 ...
- 【BZOJ-3784】树上的路径 点分治 + ST + 堆
3784: 树上的路径 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 462 Solved: 153[Submit][Status][Discuss ...
- BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]
传送门 题意: 路径有$-1,1$两种权值,求有多少路径满足权值和为$0$且有一个点将路径分成权值和为$0$的两段 第四节课本来想去上化学,然后快上课了这道题还没调出来.....可恶我想上化学 昨天两 ...
- Codeforces 888G(分治+trie)
按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...
- 【BZOJ3697】采药人的路径 点分治
[BZOJ3697]采药人的路径 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是 ...
- BZOJ.3784.树上的路径(点分治 贪心 堆)
BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...
- BZOJ3697采药人的路径——点分治
题目描述 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动.他选择的路径 ...
- BZOJ3697:采药人的路径(点分治)
Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药 ...
- 【BZOJ3784】树上的路径 点分治序+ST表
[BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...
随机推荐
- smrtlink
SMRT Link is the web-based end-to-end workflow manager for the Sequel™ System. It includes software ...
- 【c3p0】 C3P0的三种配置方式以及基本配置项详解
数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,这里只讨论程序本身负责数据源,不讨论容器管理. ---------------------------------------- ...
- dbutils封装对象,单列,一行一列(用)
基本用法:查找并封装对象与对象集合 public User findUserByNamePassword(String name,String password){ QueryRunner runne ...
- Check time of different search methods
https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...
- 2018.09.26 bzoj5221: [Lydsy2017省队十连测]偏题(数学推导+矩阵快速幂)
传送门 由于没有考虑n<=1的情况T了很久啊. 这题很有意思啊. 考试的时候根本不会,骗了30分走人. 实际上变一个形就可以了. 推导过程有点繁杂. 直接粘题解上的请谅解. 不得不说这个推导很妙 ...
- Java synchronized关键字的理解
转载自:http://blog.csdn.net/xiao__gui/article/details/8188833 在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环 ...
- Java static说明
class Person{ String name;//成员变量,实例变量 static String country = "CN";//静态变量.类变量 public void ...
- DVWA
DVWA默认的用户有5个,用户名密码如下(一个足以): admin/password gordonb/abc123 1337/charley pablo/letmein smithy/password
- 保留注释换行的python模块configparser
python语言用来解析配置文件的模块是ConfigParser,python3中是configparser模块,我在使用中发现write方法在将配置项重新写入文 件时,配置文件中的空行和注释行都会被 ...
- (连通图 模板题 无向图求割点)Network --UVA--315(POJ--1144)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...