题意:

给你一棵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. 使用JavaMail发送邮件(含文本/附件/图片)的工具类

    记录利用公司内搭建的smtp邮件服务器,使用javax mail发送邮件的程序 package com.test.mailTest; import java.util.Date; import jav ...

  2. 二次排序LincodeNo.846

    846.Multi-keyword Sort 题目要求在已经排序好的序列上进行二次排序 那么改变一下比较方法即可 bool cmp(vector<int> a,vector<int& ...

  3. C++ | C++ 基础知识 | 类型与声明

    一.类型 C++ 包含一整套基本类型,这些类型对应计算机最基本的存储单元并且展现 1.0 布尔值 一个布尔变量(bool)的取值或者是 true 或者是 false,布尔变量常用于表达逻辑运算结果. ...

  4. Unity 基于Cinemachine计算透视摄像机在地图中的移动范围

    Unity中Cinemachine的基础功能介绍可详见之前写的博客: https://www.cnblogs.com/koshio0219/p/11820654.html 本篇的重点是讨论,在给定规则 ...

  5. 1、纯python编写学生信息管理系统

    1.效果图 2.python code: class studentSys(object): ''' _init_(self) 被称为类的构造函数或初始化方法, self 代表类的实例,self 在定 ...

  6. org.springframework.core.type.classreading.ClassMetadataReadingVisitor 异常

    今天项目启动的时候发现了一个异常: Exception in thread "main" org.springframework.beans.factory.BeanDefinit ...

  7. Redis系列-存储hash主要操作命令

    Redis系列-存储篇hash主要操作函数小结 hash是一些列key value(field value)的映射表.常常用其存储一些对象实例.相对于把一个对象的各个字段存储为string,存储为ha ...

  8. 深入学习MySQL 01 一条查询语句的执行过程

    在学习SpringCloud的同时,也在深入学习MySq中,听着<mysql45讲>,看着<高性能MySQL>,本系列文章是本人学习过程的总结,水平有限,仅供参考,若有不对之处 ...

  9. 团队作业-Alpha版本发布2

    团队项目-系统设计 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/GeographicInformationScience/homework 这个作业要 ...

  10. 双指针,BFS和图论(三)

    (一)图论 1.大臣的旅费 很久以前,T王国空前繁荣. 为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任 ...