题意:

给你一棵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字典树+启发式合并)的更多相关文章

  1. 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)

    牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...

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

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

  3. Love Live!-01字典树启发式合并

    链接:https://ac.nowcoder.com/acm/contest/201/D?&headNav=www 思路:题目要求的是每个等级下的最大 简单路径中的最大异或值,那么我们为了保证 ...

  4. 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, ...

  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 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

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

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

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

  8. Chip Factory(01字典树)

    Chip Factory http://acm.hdu.edu.cn/showproblem.php?pid=5536 Time Limit: 18000/9000 MS (Java/Others)  ...

  9. 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 ...

随机推荐

  1. SSM三大框架整合思路

    1.Dao层: Mybatis的配置文件:SqlMapConfig.xml 不需要配置任何内容,需要有文件头.文件必须存在. applicationContext-dao.xml: mybatis整合 ...

  2. python之字符串的简单应用

    1.实现5+7加法运算 value = input(">>>") v1, v2 = value.split('+') c1 = int(v1) c2 = int( ...

  3. Redis入门--1.安装Redis

    redis是什么? 是完全开源免费的,用c语言编写的,是一个单线程,高性能的(key/value)内存数据库,基于内存运行并支持持久化的nosql数据库 redis能干嘛? 主要是用来做缓存,但不仅仅 ...

  4. VMware下Hadoop 2.4.1完全分布式集群平台安装与设置

    1 VM下Ubuntu安装和配置 1.1 安装Ubuntu系统  这个就不说了,不知道的可以去看看其他的博文.   1.2 集群配置     搭建一个由3台机器组成的集群: IP user/passw ...

  5. 【转】Java面试题:多继承

    招聘和面试对开发经理来说是一个无尽头的工作,虽然有时你可以从HR这边获得一些帮助,但是最后还是得由你来拍板,或者就像另一篇文章“Java 面试题:写一个字符串的反转”所说: 面试开发人员不仅辛苦而且乏 ...

  6. vs删除空白行 注释

    在vs编辑器中有时需要批量删除无用的空白行,为此,可以使用vs编辑器的查找替换功能: 1. Ctrl+H,打开替换功能框. 2.选择“使用正则表达式”,“当前文档”. 3.在查找框中输入: (?< ...

  7. CheckStyle报错的常见问题及解决方式

    CheckStyle报错的常见问题及解决方式 声明: 本文摘自百度文库.希望这篇文章提到的规范能对大家编程起到好的效果,此文不定期更新,将推出更加详尽的编程规范. 1   提示:Type is mis ...

  8. 类选择器练习:Google 案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  9. 如何编写Robot Framework测试用例1---(基本格式篇)

    引子 我们使用符合Robot Framework规范的一种表格语法来编写测试用例.用例一般会是下面这个样子 这样的表格存储到一个文件中,就是一组测试用例.RF支持多种格式,如HTML,TSV,纯文本等 ...

  10. python 线程信号量

    线程信号量和进程信号量相似 # 线程信号量 import time from threading import Semaphore from threading import Thread def t ...