题目大意:给你一棵$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. Oracle连接字符串大全

    // 在 C# 代码中用以下数据库提供程序访问 Oracle 数据库 // Oracle Data Provider for .NET / ODP.NET 使用 TNS 写法 Data Source= ...

  2. 2018.09.20 atcoder Painting Graphs with AtCoDeer(tarjan+polya)

    传送门 一道思维题. 如果没有环那么对答案有k的贡献. 如果恰为一个环,可以用polya求贡献. 如果是一个有多个环重叠的双联通的话,直接转化为组合数问题(可以证明只要每种颜色被选取的次数相同一定可以 ...

  3. 2018.09.16 loj#10241. 取石子游戏 1(博弈论)

    传送门 好像是某年的初赛题啊. 有个很显然的结论. 当n" role="presentation" style="position: relative;&quo ...

  4. arduino 与 android 通过TCP进行字节收发

    arduino #include <avr/wdt.h> #include <SoftwareSerial.h> #define FPIN 13 SoftwareSerial ...

  5. spring mvc与mybatis整合错误提示

    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L ...

  6. # 20155204 2016-2017-2 《Java程序设计》第五周学习总结

    20155204 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生时显示友好的错误信 ...

  7. Codeforces777E. Hanoi Factory 2017-05-04 18:10 42人阅读 评论(0) 收藏

    E. Hanoi Factory time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  8. HDU 1166敌兵布阵 2016-09-14 18:58 89人阅读 评论(0) 收藏

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. Linux监控本机当前状态命令

    vmstat 1.简介 vmstat命令是最常见的Linux监控工具,可以查看系统的状态值,其中包括:CPU.内存.虚拟内存.I/O情况. 2.参数说明 命令格式:  vmstat [-a] [-n ...

  10. nodejs express hi-cms

    今天看一下hi-cm是怎么写的,理解一下流程,看一些亮点 它使用express3.x写的 1.app.set, app.get app.set('port', 3000); app.get('port ...