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. MySql中的有条件插入 insert where

    假设现在我们有这样的需求:当数据库中不存在满足条件的记录时,可以插入一条记录,否则程序退出.该怎么实现? 1年以上工作经验的人应该都能立即想到:去检查一下库里有没有记录,没有就插入,有就结束. int ...

  2. 真的,kafka 入门看这一篇准没错!

    什么是 Kafka Kafka 是一个分布式流式平台,它有三个关键能力 订阅发布记录流,它类似于企业中的消息队列 或 企业消息传递系统 以容错的方式存储记录流 实时记录流 Kafka 的应用 作为消息 ...

  3. 剑指Offer58-左转字符串

    题目 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=" ...

  4. zookeeper读取事务日志、快照日志

    zookeeper的事务日志的格式如 log.xxx, xxx表示顺序序号 我使用的zookeeper版本:3.5.5 事务日志 执行命令 java -cp .:/tmp/zookeeper-3.5. ...

  5. linux网络工具nc命令

    nc是netcat的简写,有着网络界的瑞士军刀美誉.因为它短小精悍.功能实用,被设计为一个简单.可靠的网络工具. nc命令的作用 (1)实现任意TCP/UDP端口的侦听,nc可以作为server以TC ...

  6. 【Spring】Spring中的Bean - 1、Baen配置

    Bean配置 简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean 什么是Spring中的Bean? Spring可以被看作是一个 ...

  7. K8s 平台可以如何处理 Pod 预授权问题

    前言 TKEx-CSIG 是基于腾讯公有云 TKE 和 EKS 容器服务开发的内部上云容器服务平台,为解决公司内部容器上云提供云原生平台,以兼容云原生.适配自研业务.开源协同为最大特点. 业务容器上云 ...

  8. 以事实驳斥:改进你的c#代码的5个技巧(四)

    测试使用的环境:vs2019+.net core3.1 原文地址:https://www.cnblogs.com/hhhnicvscs/p/14296715.html 反驳第一条:如何检查代码中的空字 ...

  9. 超详细 安装VMware Workstation,并安装WIN10操作系统连接外网 步骤指导

    首先下载VMware Workstation15.1版本,我保存在迅雷链接里面,下载速度非常可观. 链接:https://pan.xunlei.com/s/VMRSt6hHMZXEmPZCm6gJcG ...

  10. Java编程开发之浅析Java引用机制

    对于一个Java的对象而言,存储主要分为两种,一种是内存堆(Heap),内存堆是无序的,主要用来存放创建的Java对象:一种是内存栈(Stack),主要用来存放Java引用,然后在管理过程使用Java ...