【xsy1214】 异或路径(xorpath) 点分治+可持久化trie
题目大意:给你一棵$n$个点的树,每个点有一个点权$x$,问你所有路径中点权异或和最大的路径的异或和
数据范围:$n≤30000$,$x≤2^{31}-1$。
如果是边上有点权的话非常简单,直接一个$trie$就可以水过去了。
然而这题是点权,非常烦人。我们考虑用点分治去解决。
假设当前需要遍历的树的重心是$x$,我们开一个可持久化$trie$,我们用$son[x][i]$表示$x$的第$i$个儿子(我们假设总共有$p_x$个),将从$son[x][i]$出发的路径异或和加入第$[i,p_x]$个$trie$树中,当我们遍历出一条从$x$出发,经过$son[x][i]$的路径时,我们把这个路径的异或和放入第$i-1$个$trie$树中进行搜索。
我们已知点分治的时间复杂度是$O(n\ log\ n)$,由于这里面套了一个可持久化$trie$,那么时间复杂度就是$O(n\ log\ n\ log_2^{max{x}}$。
然后我的$trie$树出了锅,路径长度的最后一个二进制位没有被塞进$trie$中,然后成功$GG$
#include<bits/stdc++.h>
#define M 100005
#define INF 19260817
using namespace std; struct edge{int u,next;}e[M*]={}; int head[M]={},Use=;
void add(int x,int y){Use++;e[Use].u=y;e[Use].next=head[x];head[x]=Use;} int num[M]={},vis[M]={}; int siz[M]={}; 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];
}
}
int minn,minid;
void dfsmax(int x,int fa,int fasiz){
int maxn=fasiz-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,fasiz);
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;
} struct trie{
int a[];
}a[M*]={};int root[M]={},use=; void add(int &x,int zhi,int wei){
a[++use]=a[x]; x=use; int hh=;
if(wei<) return;
if((<<wei)&zhi) hh=;
add(a[x].a[hh],zhi,wei-);
}
int query(int x,int zhi,int wei){
if(wei<||x==) return ;
int hh=,ans=;
if((<<wei)&zhi) hh=;
if(!a[x].a[hh]) return query(a[x].a[hh^],zhi,wei-);
else return (<<wei)+query(a[x].a[hh],zhi,wei-);
} void dfsdis(int x,int fa,int hh,int cnt){
hh^=num[x];
add(root[cnt],hh,);
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==){
dfsdis(e[i].u,x,hh,cnt);
}
} int ans=; void query(int x,int fa,int hh,int cnt){
hh^=num[x];
int now=query(root[cnt-],hh,);
ans=max(ans,now);
ans=max(ans,hh);
for(int i=head[x];i;i=e[i].next)
if(e[i].u!=fa&&vis[e[i].u]==){
query(e[i].u,x,hh,cnt);
}
} void calc(int x){
int cnt=;
for(int i=head[x];i;i=e[i].next)
if(vis[e[i].u]==){
cnt++; root[cnt]=root[cnt-];
dfsdis(e[i].u,x,,cnt);
}
cnt=;
for(int i=head[x];i;i=e[i].next)
if(vis[e[i].u]==){
cnt++;
ans=max(ans,num[x]);
query(e[i].u,x,num[x],cnt);
}
use=; memset(root,,(cnt+)<<);
} void dfs(int x){
x=makeroot(x); vis[x]=;
calc(x);
for(int i=head[x];i;i=e[i].next)
if(vis[e[i].u]==) dfs(e[i].u);
} int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n; scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",num+i);
for(int i=;i<n;i++){
int x,y; scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dfs();
cout<<ans<<endl;
}
【xsy1214】 异或路径(xorpath) 点分治+可持久化trie的更多相关文章
- [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)
[FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...
- BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)
BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...
- bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】
其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...
- [FJOI2015]火星商店问题(线段树分治+可持久化Trie)
重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...
- 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie
感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...
- P4735 最大异或和 /【模板】可持久化Trie
//tire的可持久化 //线段树的可持久化——主席树 //可持久化的前提:本身的拓扑结构在操作时不变 //可以存下来数据结构的所有历史版本 //核心思想:只记录每一个版本与前一个版本不一样的地方 / ...
- [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】
题目链接:BZOJ - 4103 题目分析 THUSC滚粗之后一直没有写这道题,从来没写过可持久化Trie,发现其实和可持久化线段树都是一样的.嗯,有些东西就是明白得太晚. 首先Orz ZYF-ZYF ...
- 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)
点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...
- BZOJ_3697_采药人的路径_点分治
BZOJ_3697_采药人的路径_点分治 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性 ...
随机推荐
- 【Linux】Jenkins配置和使用(二)
摘要 本章介绍Jenkins的简单使用,关于Jenkins的安装,参照[Linux]Jenkins安装(一) 事例说明:在linux环境下,安装的jenkins,集成svn,tomcat的环境,项目是 ...
- 2018.07.29~30 uoj#170. Picks loves segment tree VIII(线段树)
传送门 线段树好题. 维护区间取两种最值,区间加,求区间两种历史最值,区间最小值. 自己的写法调了一个晚上+一个上午+一个下午+一个晚上并没有调出来,90" role="prese ...
- 进度条ProgressBar
在本节中,作者只写出了进度条的各种样式,包括圆形.条形,还有自定义的条形,我想如果能让条形进度条走满后再继续从零开始,于是我加入了一个条件语句.作者的代码中需要学习的是handler在主线程和子线程中 ...
- Windows 下使用 GCC
MinGw 是 Minimal GNU on Windows 的缩写,允许在 GNU/Linux 和 Windows 平台生成本地的 Windows 程序而不需要第三方运行时库.本文主要介绍 MinG ...
- (KMP扩展 利用循环节来计算) Cyclic Nacklace -- hdu -- 3746
http://acm.hdu.edu.cn/showproblem.php?pid=3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others ...
- (最小生成树 Prim) Highways --POJ --1751
链接: http://poj.org/problem?id=1751 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1150 ...
- 一个简单 Go Web MVC 框架实现思路
需要的知识点 为了防止你的心里不适,需要以下知识点: Go 基本知识 Go 反射的深入理解 使用过框架 Go Web 服务器搭建 package main import ( "fmt&quo ...
- Python学习-36.Python中的字典解释
具体同列表解释,也是使用if来进行过滤 例子,生成一个新的字典,并且是原来字典的键值交换. mydict={'Tom':18,'Mary':20} print({value:key for key,v ...
- 今天犯了一个StringBuilder构造函数引起的二逼问题。
在.Net里,StringBuilder的构造函数有很多,最常用的是无参的构造函数,默认分配16个字符的空间.其次就是填写StringBuilder空间的带一个Int32的构造函数,这个在优化代码的时 ...
- Windows Phone 放开政策 - 应用内支付(IAP)可加入三方支付
Windows Phone 应用商店在 今年(2013)11月04号 修改了商店政策 允许公司账户的应用使用三方支付SDK. 通过 App certification requirements cha ...