题目大意:给你一棵$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的更多相关文章

  1. [FJOI2015]火星商店问题(线段树分治,可持久化,Trie树)

    [FJOI2015]火星商店问题 前天考了到线段树分治模板题,全场都切了,就我不会QAQ 于是切题无数的Tyher巨巨就告诉我:"你可以去看看火星商店问题,看了你就会了." 第一道 ...

  2. BZOJ.4137.[FJOI2015]火星商店问题(线段树分治 可持久化Trie)

    BZOJ 洛谷 一直觉得自己非常zz呢.现在看来是真的=-= 注意题意描述有点问题,可以看BZOJ/洛谷讨论. 每个询问有两个限制区间,一是时间限制\([t-d+1,t]\),二是物品限制\([L,R ...

  3. bzoj 4137 [FJOI2015]火星商店问题【CDQ分治+可持久化trie】

    其实我不太清楚这个应该叫CDQ分治还是整体二分 参考:http://blog.csdn.net/lvzelong2014/article/details/78688727 一眼做法是线段树套可持久化t ...

  4. [FJOI2015]火星商店问题(线段树分治+可持久化Trie)

    重新写一年前抄题解的那题,当时我啥都不会只是Ctrl+C,Ctrl+V写过的题,今天重新写一遍. 题解: 不会线段树分治,还是学一下这东西吧,这是我的第一道线段树分治. 首先对于特殊商品,可以直接可持 ...

  5. 【洛谷P4585】 [FJOI2015]火星商店问题 线段树分治+可持久化trie

    感觉这个线段树分治和整体二分几乎相同啊~ code: #include <bits/stdc++.h> #define MAX 100300 #define ll long long #d ...

  6. P4735 最大异或和 /【模板】可持久化Trie

    //tire的可持久化 //线段树的可持久化——主席树 //可持久化的前提:本身的拓扑结构在操作时不变 //可以存下来数据结构的所有历史版本 //核心思想:只记录每一个版本与前一个版本不一样的地方 / ...

  7. [BZOJ 4103] [Thu Summer Camp 2015] 异或运算 【可持久化Trie】

    题目链接:BZOJ - 4103 题目分析 THUSC滚粗之后一直没有写这道题,从来没写过可持久化Trie,发现其实和可持久化线段树都是一样的.嗯,有些东西就是明白得太晚. 首先Orz ZYF-ZYF ...

  8. 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)

    点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...

  9. BZOJ_3697_采药人的路径_点分治

    BZOJ_3697_采药人的路径_点分治 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性 ...

随机推荐

  1. Java中的内存划分

    Java程序在运行时,需要在内存中分配空间.为了提高运行效率,就对数据进行了不同的空间划分.因为每一片区域都有特定的数据处理方式和内存管理方式. 具体分为5种内存空间: 程序计数器:保证线程切换后能恢 ...

  2. 安装指定版本的docker

    安装 Docker 从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE. Docker CE 即社区免费版,Docker EE 即 ...

  3. python数据类型4

    一浮点数 什么叫做浮点数:浮点数就相当于小数,但是浮点数不包括无限循环又不重复的小数. 小数分为 有限小数和无限小数 无限小数又分为 无限循环小数和无限不循环小数 而 浮点数就是有限小数和无限循环小数 ...

  4. 2018.09.30 bzoj2288:生日礼物(贪心+线段树)

    传送门 线段树经典题目. 每次先找到最大子段和来更新答案,然后利用网络流反悔退流的思想把这个最大字段乘-1之后放回去. 代码: #include<bits/stdc++.h> #defin ...

  5. 2018.09.15[POI2008]BLO-Blockade(割点)

    描述 There are exactly nn towns in Byteotia. Some towns are connected by bidirectional roads. There ar ...

  6. 文件权限命令 linux

    chmod 777 文件名/文件夹名         拥有所有权限 http://www_xpc8_com/ chmod 755 文件名/文件夹名         属主有所有权限,群组和其他有读.执行 ...

  7. Notification的功能和用法 加薪通知

    实现通知栏消息的生成和消除 MainActivity.java        public class MainActivity extends Activity   {       static f ...

  8. Shiro ini 过滤器

    http://shiro.apache.org/web.html#Web-WebINIconfiguration Filter Name Class anon org.apache.shiro.web ...

  9. HDU2553 N皇后问题 2016-07-24 13:56 283人阅读 评论(0) 收藏

    N皇后问题 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是, ...

  10. hdu 1799 循环多少次?

    题目 题意:给出n,m,其中m表示有几层循环,求循环的次数 ①如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算: ②如果代码中出现 fori=1;i<=n ...