Query on A Tree

Problem Description

Monkey A lives on a tree, he always plays on this tree.

One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.

Monkey A gave a value to each node on the tree. And he was curious about a problem.

The problem is how large the xor result of number x and one node value of label y can be, when giving you a non-negative integer x and a node label u indicates that node y is in the subtree whose root is u(y can be equal to u).

Can you help him?

给出一棵根为\(1\)的树,每个点都有权值,\(q\)次询问,每次询问以\(u\)为根的子树里和\(x\)异或的最大值是多少

如果询问是以\(1\)为根的话,我们可以直接把所有点放到\(01\)字典树里去,然后每次拿\(x\)去匹配

现在不是以\(1\)为根,可以考虑树上启发式合并,先处理轻儿子,然后处理重儿子,保留重儿子的子树建出来的字典树,然后把其他子树里的点放进去

从高位到低位贪心匹配即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n,w[MAXN],q,son[MAXN],sz[MAXN],ret[MAXN];
vector<int> G[MAXN];
vector<pair<int,int> > Q[MAXN];
struct Trie{
int tot,ch[MAXN<<4][2];
void clear(){ tot = 0, ch[0][0] = ch[0][1] = 0; }
int newnode(){ tot++; ch[tot][0] = ch[tot][1] = 0; return tot; }
void insert(int x){
int p = 0;
for(int i = 30; ~i; i--){
int nxt = (x&(1<<i))?1:0;
if(!ch[p][nxt]) ch[p][nxt] = newnode();
p = ch[p][nxt];
}
}
int match(int x){
int res = 0, p = 0;
for(int i = 30; ~i; i--){
int nxt = (x&(1<<i))?0:1;
if(ch[p][nxt]) res |= (1<<i), p = ch[p][nxt];
else p = ch[p][nxt^1];
}
return res;
}
}trie;
void dfs(int u){
sz[u] = 1; son[u] = 0;
for(int v : G[u]){
dfs(v); sz[u] += sz[v];
if(sz[v]>sz[son[u]]) son[u] = v;
}
}
void update(int u){
trie.insert(w[u]);
for(int v : G[u]) update(v);
}
void search(int u, bool clear){
for(int v : G[u]) if(v!=son[u]) search(v,true);
if(son[u]) search(son[u],false);
for(int v : G[u]) if(v!=son[u]) update(v);
trie.insert(w[u]);
for(auto que : Q[u]) ret[que.second] = trie.match(que.first);
if(clear) trie.clear();
}
void solve(){
for(int i = 1; i <= n; i++){
G[i].clear(); Q[i].clear();
scanf("%d",&w[i]);
}
for(int i = 2; i <= n; i++){
int par; scanf("%d",&par);
G[par].emplace_back(i);
}
dfs(1);
for(int i = 1; i <= q; i++){
int u, x; scanf("%d %d",&u,&x);
Q[u].emplace_back(make_pair(x,i));
}
search(1,true);
for(int i = 1; i <= q; i++) printf("%d\n",ret[i]);
}
int main(){
while(scanf("%d %d",&n,&q)!=EOF) solve();
return 0;
}

HDU6191 Query on A Tre【dsu on tree + 01字典树】的更多相关文章

  1. HDU6191 Query on A Tree (01字典树+启发式合并)

    题意: 给你一棵1e5的有根树,每个节点有点权,1e5个询问(u,x),问你子树u中与x异或最大的值是多少 思路: 自下而上启发式合并01字典树,注意合并时清空trie 线段树.字典树这种结构确定的数 ...

  2. HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

    题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...

  3. HDU6191(01字典树启发式合并)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  4. HDU5589 Tree【分块 01字典树】

    HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u ...

  5. HDU 6191 Query on A Tree(字典树+离线)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  6. HDU 4757 Tree(可持续化字典树,lca)

    题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...

  7. HDU5589:Tree(莫队+01字典树)

    传送门 题意 略 分析 f[u]表示u到根的边的异或 树上两点之间的异或值为f[u]^f[v], 然后将查询用莫队算法分块,每个点插入到字典树中,利用字典树维护两点异或值大于等于M复杂度O(N^(3/ ...

  8. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  9. trie tree(字典树)

    hihocoder题目(http://hihocoder.com/problemset):#1014 trie树 #include <iostream> using namespace s ...

随机推荐

  1. Jenkins+GitLab+SonnarQube搭建CI/CD全流程

    1. CI/CD 1.1 CI - 持续集成 持续集成( Continuous integration , 简称 CI )指的是,频繁地(一天多次)将代码集成到主干.持续集成的目的就是让产品可以快速迭 ...

  2. Dubbo+Zookeeper(二)Dubbo架构

    上次更新博客已经是一年前,这一年发生了很多事,并不顺利,甚至有些痛苦,不过不管怎样,不要停止学习,只有学习才能让你变强,应对更多不安定. 一.RPC概念 Dubbo服务是一个RPC框架,那我们首先就要 ...

  3. 拍摄、剪辑vlog的思路

    这篇文章是看了很多狂阿弥_ 的作品后 产生的一些小小总结.这些技法只是锦上添花,阿弥作品真正好的地方在于他细腻的情感,真实的对白,和打动人心的满分作文. 优秀的Vlog ,在于它和观众产生的情感共鸣. ...

  4. 【Git】Git初始化一个仓库

    文章目录 初始化仓库 检查当前文件状态 跟踪新文件 提交更新 跳过使用暂存区域 移除文件 添加远程仓库 推送到远程仓库 简单记录-慕课网 从0开始 独立完成企业级Java电商网站开发 Git初始化一个 ...

  5. 【Linux】linux rinetd 端口转发部署

    linux下简单好用的工具rinetd,实现端口映射/转发/重定向 Rinetd是为在一个Unix和Linux操作系统中为重定向传输控制协议(TCP)连接的一个工具.Rinetd是单一过程的服务器,它 ...

  6. 性能测试工具locust简单应用

    简介 Locust是一种易于使用的分布式用户负载测试工具.可用于对网站(或系统)负载测试,并依据响应数据计算出系统支持的并发用户数. 安装及调试(以下操作在windows环境下进行) Locust基于 ...

  7. Zju1100 Mondriaan

    题目描述 有一个m行n列的矩阵,用1*2的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法? 你只需要求出覆盖方法总数mod p的值即可. 输入格式 三个整数数n,m,p,m< ...

  8. apscheduler(定时任务) 基于redis持久化配置操作

    apscheduler(定时任务) 基于redis持久化配置操作 安装模块 pip install apscheduler 导入模块配置 ## 配置redis模块 from apscheduler.j ...

  9. unity3D进阶

    前言 在之前的例子中,我们都没有用到unity的精髓,例如地形系统.物理系统.粒子系统等,本文记录unity3D的进阶简单应用 前期准备 https://unity.cn/releases/full/ ...

  10. 在OpenDaylight controller上开发App

    安装环境:Ubuntu18.04 一.安装依赖 1. 安装JDK: sudo apt update sudo apt install openjdk-8-jdk-headless 选择默认的 JDK: ...