HDU6191 Query on A Tre【dsu on tree + 01字典树】
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字典树】的更多相关文章
- HDU6191 Query on A Tree (01字典树+启发式合并)
题意: 给你一棵1e5的有根树,每个节点有点权,1e5个询问(u,x),问你子树u中与x异或最大的值是多少 思路: 自下而上启发式合并01字典树,注意合并时清空trie 线段树.字典树这种结构确定的数 ...
- HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序
题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...
- HDU6191(01字典树启发式合并)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- HDU5589 Tree【分块 01字典树】
HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u ...
- HDU 6191 Query on A Tree(字典树+离线)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- HDU 4757 Tree(可持续化字典树,lca)
题意:询问树上结点x到结点y路上上的权值异或z的最大值. 任意结点权值 ≤ 2^16,可以想到用字典树. 但是因为是询问某条路径上的字典树,将字典树可持续化,字典树上的结点保存在这条路径上的二进制数. ...
- HDU5589:Tree(莫队+01字典树)
传送门 题意 略 分析 f[u]表示u到根的边的异或 树上两点之间的异或值为f[u]^f[v], 然后将查询用莫队算法分块,每个点插入到字典树中,利用字典树维护两点异或值大于等于M复杂度O(N^(3/ ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- trie tree(字典树)
hihocoder题目(http://hihocoder.com/problemset):#1014 trie树 #include <iostream> using namespace s ...
随机推荐
- GitLab的安装及使用
Gitlab环境部署 安装依赖包. sudo yum install -y curl policycoreutils-python openssh-server 设置SSH开机自启动并启动SSH服 ...
- Spring Security OAuth2.0认证授权四:分布式系统认证授权
Spring Security OAuth2.0认证授权系列文章 Spring Security OAuth2.0认证授权一:框架搭建和认证测试 Spring Security OAuth2.0认证授 ...
- AndroidStuidio安装
前言 端午小长假,安卓入门走起 正文 下载AndroidStudio 这里给出google的官网 https://developer.android.com/studio 注意,因404原因,如果你无 ...
- UnityToLaya小插件-找出空格并替换
unity导出的文件中经常会出现带有空格的节点或者文件夹 而这些空格在本地开发测试过程中不会出现,当这些带有空格路径的文件需要放到网络上时,就出现问题了 所以这里写了一个简单的查找并清理空格的插件, ...
- Docker学习笔记之进入容器Bash
我们在创建容器的时候,如果容器的命令(command)不是/bin/bash的时候,使用docker attach命令是会卡住进不去容器的bash shell的.如下图所示: 所以,这里记录一个可以进 ...
- 【网络】trunk和vlan配置
篇一 : trunk配置和vlan配置 trunk配置 Switch>enable ? ? ?//进入特权模式 Switch#conf t ? ? ?//进入配置模式 Switch(config ...
- 使用memory_profiler异常
在使用memory_profiler模块0.55.0版本执行命令诊断程序内存用量时,遇到下面错误: C:\Users\Chen\Desktop\python_doc\第四模块课件>python ...
- 求得二叉搜索树的第k小的元素
求得二叉搜索树的第k小的元素 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 须知:二叉搜索树,又叫二叉排序树,二叉查找树.特点是:左子树的所有元素都小于等 ...
- CSGO项目
#include <Windows.h> #include <sstream> #include <iostream> #include <math.h> ...
- 解读腾讯敏捷研发核心驱动力 腾讯TAPD TAPD 2020-12-17
解读腾讯敏捷研发核心驱动力 腾讯TAPD TAPD 2020-12-17