【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< ...
随机推荐
- An integration of deep learning and neuroscience
Recently, I have read a paper about the integration of deep learing and neuroscience, which elaborat ...
- 20145226夏艺华 《Java程序设计》第8周学习总结
教材学习内容总结 学习目标 了解NIO 会使用Channel.Buffer与NIO2 会使用日志API.国际化 会使用正则表达式 了解JDK8增强功能 第14章 NIO与NIO2 14.1 认识NIO ...
- [转载红鱼儿]delphi 实现微信开发(1)
大体思路: 1.用户向服务号发消息,(这里可以是个菜单项,也可以是一个关键词,如:注册会员.) 2.kbmmw web server收到消息,生成一个图文消息给微信,在图文消息中做好自己的url,在u ...
- 基于beego orm 针对oracle定制
目前golang的ORM对oracle支持都没有mysql那样完整,一个orm要同时兼容mysql和oracle由于在sql语法上区别,会使整orm变的非常臃肿. 本项目是在beego orm上修改, ...
- 电信网上营业厅-客户充值缴费时间段数据挖掘--spss
最近研究分析了“云南电信网上营业厅”e9宽带续约缴费的数据,目前宽带续约量为171人,今天需要谈论的是:如何利用SPSS挖掘出“客户充值缴费的时间段”客户喜欢在哪个时间段来网厅进行充值缴费 云南电信网 ...
- (最小生成树) Jungle Roads -- POJ -- 1251
链接: http://poj.org/problem?id=1251 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2177 ...
- uva 579 ClockHands 几何初接触 求时针与分针的夹角
貌似是第一次接触几何题... 求时针与分针的夹角,这不是小学生的奥数题么.我小时候也想过这问题的. 每过一小时时针走1/12*360=30度,每过一分钟时针走1/60*30=0.5度,分针走1/60* ...
- java.util.Date与java.sql.Date的关系和转换方法(转)
在ResultSet中我们经常使用的setDate或getDate的数据类型是java.sql.Date,而在平时java程序中我们一般习惯使用 java.util.Date. 因此在DAO层我们经常 ...
- Example11(June 9,2015)
%--------------sort------------------------------- >> A=[ ; ; ] A = >> B=sort(A,)%A(:,)& ...
- SSH登录警告(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!)
在配置本机与docker容器实现ssh无密码访问时出现以下报错 # federico @ linux in ~ [18:35:52] C:127$ sudo ssh-copy-id -i .ssh/i ...