HDU 4757 树链剖分+可持久化字典树
来源:互联网 发布:文件粉碎软件 编辑:程序博客网 时间:2024/06/14 13:46
题目链接
思路:
对于这种询问树的路径的题,第一反应就是树链剖分,但与多个给定值异或后的最大值却没有办法去高效维护。
考虑另外的思路。
有关异或的数据结构,自然会想到01字典树,联系一个经典问题:
求一个数与一个数集中的某个数异或的最大值
而对于此题,每一个询问相当于给定了一个数集,只不过其中的数是一条路径上所有顶点的值。
故可以从根出发,对于每一个节点,都维护一个从根到它自己所经过的所有顶点值的前缀字典树,对于询问就能通过差分的思想来对给定值进行匹配,从而得到异或的最大值。
注意要单独计算给定值与LCA的异或值,这题我是用的树链剖分来求LCA
代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int A = 1e5 + 10;class Gra{public: int v,next;}G[A<<1];class Trie{public: int ne[2],cnt;}T[A<<5];int val[A],head[A],root[A],tot,twt,n,m;int dep[A],son[A],fa[A],siz[A],top[A];void init(){ tot = twt = T[0].cnt = 0; memset(T[0].ne,0,sizeof(T[0].ne)); memset(head,-1,sizeof(head));}void add(int u,int v){G[tot].v = v;G[tot].next = head[u];head[u] = tot++;}void input(){ for(int i=1 ;i<=n ;i++) scanf("%d",&val[i]); for(int i=1 ;i< n ;i++){ int u,v;scanf("%d%d",&u,&v); add(u,v);add(v,u); }}void dfs(int u,int pre,int d){ son[u] = -1;siz[u] = 1; dep[u] = d;fa[u] = pre; for(int i=head[u] ;i!=-1 ;i=G[i].next){ int v = G[i].v; if(v == pre) continue; dfs(v,u,d+1); siz[u] += siz[v]; if(son[u] == -1 || siz[son[u]] < siz[v]){ son[u] = v; } }}void dfs(int u,int tp){ top[u] = tp; if(son[u] == -1) return; dfs(son[u],tp); for(int i=head[u] ;i!=-1 ;i=G[i].next){ int v = G[i].v; if(v == son[u] || v == fa[u]) continue; dfs(v,v); }}int LCA(int u,int v){ while(top[u] != top[v]){ if(dep[top[u]] < dep[top[v]]) swap(u,v); u = fa[top[u]]; } return dep[u]>dep[v]?v:u;}int insert(int y,int v){ int res,x; res = x = ++twt;T[x] = T[y]; for(int i=16 ;i>=0 ;i--){ int c = (v>>i)&1; int now = ++twt; T[now] = T[T[x].ne[c]]; T[now].cnt++; T[x].ne[c] = now; x = now; } return res;}void dfs(int u){ root[u] = insert(root[fa[u]],val[u]); for(int i=head[u] ;i!=-1 ;i=G[i].next){ int v = G[i].v; if(v == fa[u]) continue; dfs(v); }}int query(int x,int y,int z,int v){ int ans = val[z]^v,res = 0;z = root[z]; for(int i=16 ;i>=0 ;i--){ int c = (v>>i)&1; int num = T[T[x].ne[c^1]].cnt + T[T[y].ne[c^1]].cnt - 2*T[T[z].ne[c^1]].cnt; if(num>0) res |= (1<<i),c^=1; x = T[x].ne[c],y = T[y].ne[c],z = T[z].ne[c]; } return max(ans,res);}void solve(){ dfs(1,0,1);dfs(1,1);dfs(1); for(int i=1 ;i<=m ;i++){ int x,y,z;scanf("%d%d%d",&x,&y,&z); printf("%d\n",query(root[x],root[y],LCA(x,y),z)); }}int main(){ while(~scanf("%d%d",&n,&m)){ init();input(); solve(); } return 0;}
阅读全文
0 0
- hdu-4757-Tree-树链剖分+可持久化字典树
- HDU 4757 树链剖分+可持久化字典树
- HDU 4757 可持久化字典树(Trie)
- hdu 4757 Tree(可持久化字典树)
- Hdu-4757 Tree(可持久化字典树)
- hdu 4757 Tree(可持久化字典树)
- HDU 6191 DFS序+可持久化字典树
- 可持久化字典树
- HDU 4757 可持久化trie树
- BZOJ 3261 可持久化字典树
- BZOJ3166 && BZOJ3261 可持久化字典树
- hdu4757(LCA+可持久化字典树)
- 模板 可持久化字典树
- bzoj4546 -- 可持久化字典树
- hdu6191 可持久化字典树
- 2017 icpc广西邀请赛 K.Query on A Tree (hdu 6191)可持久化字典树
- HDU 6191 Query on A Tree [可持久化字典树]
- HDU 6191 Query on A Tree ( DFS序 + 可持久化字典树 )
- [RK3288][Android6.0] AUDIO_BECOMING_NOISY作用
- Mac Shell脚本中使用echo的-n参数不生效
- 数据结构--希尔排序(ShellSort)思想与实现
- 第十三节:下拉选择框Select
- linux环境程序在链接时和运行时搜索动态库的顺序
- HDU 4757 树链剖分+可持久化字典树
- rcS启动
- Android/Java中汉字转成拼音
- SQL优化的几个方向
- ICC---data setup
- CSS块级元素和行内元素
- ACPI 热拔插
- myeclipse 点击部署按钮不起作用 部署不了
- Android微信相机 高仿