HDU6191 Query on A Tree (01字典树+启发式合并)
题意:
给你一棵1e5的有根树,每个节点有点权,1e5个询问(u,x),问你子树u中与x异或最大的值是多少
思路:
自下而上启发式合并01字典树,注意合并时清空trie
线段树、字典树这种结构确定的数据结构,启发式合并的时候不需要考虑次序,复杂度都是nlogn
代码:
2200 / 10000ms , 60 / 128 M
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x))
#define LLONG_MAX 9223372036854775807 using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e6+;
const int maxm = 1e5+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int tot;
int n, q;
int a[maxm];
int root[maxm];
int trie[maxn][];
vector<int>v[maxm];
queue<int>pool;
int build(){
if(!pool.empty()){
int x = pool.front();
pool.pop();
return x;
}
++tot;
return tot;
}
void insert(int root, int t){
for(int i = ; i >= ; i--){
int x = (t>>i)&;
if(!trie[root][x])trie[root][x]=build();
root = trie[root][x];
}
return;
}
int query(int root, int t){
int ans = ;
for(int i = ; i >= ; i--){
int x = (t>>i)&;
if(trie[root][x^]){
ans|=(<<i);
root = trie[root][x^];
}
else root = trie[root][x];
}
return ans;
}
vector<PI>ask[maxn];
void del(int x){
if(!x)return;
pool.push(x);
return;
}
int merge(int p, int q){
if(!p)return q;
if(!q)return p;
trie[p][] = merge(trie[p][], trie[q][]);
trie[p][] = merge(trie[p][], trie[q][]);
trie[q][]=trie[q][]=;
del(q);
return p;
}
int ans[maxn];
void dfs(int x){
root[x] = build();
insert(root[x], a[x]);
for(int i = ; i < (int)v[x].size(); i++){
int y = v[x][i];
dfs(y);
root[x] = merge(root[x],root[y]);
}
for(int i = ; i < (int)ask[x].size(); i++){
ans[ask[x][i].fst] = query(root[x], ask[x][i].sc);
}
return;
} int main(){
while(~scanf("%d %d", &n, &q)){
tot = ;
while(!pool.empty())pool.pop();
mem(trie,);
for(int i = ; i <= n; i++){
v[i].clear();
ask[i].clear();
root[i]= ;
scanf("%d", &a[i]);
}
for(int i = ; i <= n; i++){
int x;
scanf("%d", &x);
v[x].pb(i);
}
for(int i = ; i <= q; i++){
int u, x;
scanf("%d %d", &u, &x);
ask[u].pb(make_pair(i,x));
}
dfs();
for(int i = ; i <= q; i++){
printf("%d\n",ans[i]);
}
del(root[]);
}
return ;
}
/*
2 2
1 2
1
1 3
2 1 3 2
1 2 3
1 1
3 4
1 3 11 4
1 2 3 4 5 6 7 8 9 10 11
1 1 1 2 2 3 4 4 4 5
2 5
3 6
1 2
8 7 100000 2
1 55
2 33
*/
HDU6191 Query on A Tree (01字典树+启发式合并)的更多相关文章
- 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)
牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...
- HDU6191(01字典树启发式合并)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- Love Live!-01字典树启发式合并
链接:https://ac.nowcoder.com/acm/contest/201/D?&headNav=www 思路:题目要求的是每个等级下的最大 简单路径中的最大异或值,那么我们为了保证 ...
- 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, ...
- 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 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序
题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...
- HDU5589 Tree【分块 01字典树】
HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u ...
- Chip Factory(01字典树)
Chip Factory http://acm.hdu.edu.cn/showproblem.php?pid=5536 Time Limit: 18000/9000 MS (Java/Others) ...
- Codeforces 979 D. Kuro and GCD and XOR and SUM(异或和,01字典树)
Codeforces 979 D. Kuro and GCD and XOR and SUM 题目大意:有两种操作:①给一个数v,加入数组a中②给出三个数x,k,s:从当前数组a中找出一个数u满足 u ...
随机推荐
- 24.python中xlwt模块用法详解
1.创建并保存一个excel 创建一个工作簿,设置编码格式为“utf-8”,默认格式是ASCII,为了方便写入中文,一般都要设置成UTF-8 import xlwt wb = xlwt.Workboo ...
- Fastadmin 如何引入 layui 模块
FastAdmin基于RequireJS进行前端JS模块的管理,因此如果我们需要再引入第三方JS插件,则必按照RequireJS的规则进行载入.如果你还不了解什么是RequireJS,可以先简单了解下 ...
- 论Java中的抽象类与接口
目录 抽象类和抽象方法 定义 与普通类的区别以及注意点: 抽象类的作用 接口 定义 示例 注意 作用 最后:接口与抽象类的异同 使用场景 借鉴 抽象类和抽象方法 定义 抽象方法和抽象类都必须被abst ...
- Google 开源的 Python 命令行库:fire 实现 git 命令
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 小程序和wepy做循环渲染如何点击拿到相对应的值
数据和其他的就忽略,简单上手,wepy的for渲染方式改成对应的就行,传参触发不用改 <view wx:for="{{list}}"> {{item.title}} & ...
- pinpoint实现告警推送至钉钉和微信群
前言 在前面的文章中,我们学习了如何通过java实现将消息发送到钉钉.和将消息发送到微信群聊. 基于上述基础,我们今天来接入pinpoint的告警,发送到钉钉群. 实操前准备 开始之前,推荐阅读一下, ...
- 常见基本数据结构——树,二叉树,二叉查找树,AVL树
常见数据结构——树 处理大量的数据时,链表的线性时间太慢了,不宜使用.在树的数据结构中,其大部分的运行时间平均为O(logN).并且通过对树结构的修改,我们能够保证它的最坏情形下上述的时间界. 树的定 ...
- DP-Fibonacci
善于发现 DP 中的 Fibonacci 我们在做 DP 题时 , 会发现有一些题 类似于找规律的题 ,观察测试样例 , 要对数据敏感 , 比如输入 2 输出 1 , 输入 3 就输出 2 …… ...
- js强制限制输入允许两位小数
<input type="text" value="@item.CostCash.Value.ToString("#0.00")" c ...
- Android Linker简介
简单介绍Android linker的基础知识,基于Android 10分支. linker的作用 考虑简单的HelloWorld程序. $ tree . . |-- jni | |-- Androi ...