HDU 6191 Query on A Tree(字典树+离线)
Query on A Tree
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 1238 Accepted Submission(s): 444
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?
For each test case there are two positive integers n and q, indicate that the tree has n nodes and you need to answer q queries.
Then two lines follow.
The first line contains n non-negative integers $V_1,V_2,\cdots,V_n$, indicating the value of node i.
The second line contains n-1 non-negative integers $F_1,F_2,\cdots\,F_{n-1}$, $F_i$ means the father of node $i+1$.
And then q lines follow.
In the i-th line, there are two integers u and x, indicating that the node you pick should be in the subtree of u, and x has been described in the problem.
$2 \leq n,q \leq 10^5$
$0 \leq V_i \leq 10^9$
$1 \leq F_i \leq n$, the root of the tree is node 1.
$1 \leq u \leq n,0 \leq x \leq 10^9$
2 2 1 2 1 1 3 2 1
很久都没写过博客了qwq,重新写起了久违的博客。
其实前几天才做了18年的湖北省赛的网络同步赛,I题完全就是这个题的弱化版,而且数据还很水,被我写错了一个地方还AC了。
经人提点后,才发现对于一颗树上的每一个节点以及他的子节点经过DFS序可以构成一个连续的区间(转换成区间后就完全就是跟湖北省赛的I一模一样的问题,实在是无力吐槽),但是有一个需要注意的地方,dfs序的标号与原先的节点标号是不一样的,所以需要用一个数组记录他们之间的映射关系,然后通过离线即可解决问题。
关于离线的具体操作,就是将所有的询问保存下来,然后按照左端点的位置从大到小排序,然后从大到小插入大于每个询问值对应的二进制到01字典树中,同时更新或者标记对应点的id,如果查询时遇到id的值小于等于询问的右区间即可取得区间异或的最大值,否则反之。
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <istream>
#include <iterator>
#include <list>
#include <map>
#include <new>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
# ifdef __GNUC__
# if __cplusplus > 199711L
# include <unordered_set>
# include <unordered_map>
# else
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using tr1::unordered_map;
using tr1::unordered_set;
# endif
# else
# include <unordered_map>
# include <unordered_set>
# endif
#define FOR(i,a,n) for(register int i=(a),_=(n)+1;i<_;++i)
#define FIR(i,n,a) for(register int i=(n),_=(a)-1;i>_;--i)
#define all(a) (a).begin(),(a).end()
#define vlb(a,n) (lower_bound(all(a),n)-(a).begin())
#define vub(a,n) (upper_bound(all(a),n)-(a).begin())
#define vlbx(a,n) ((a)[(lower_bound(all(a),n)-(a).begin())])
#define vubx(a,n) ((a)[(upper_bound(all(a),n)-(a).begin())])
#define reunique(a) (a).resize(unique(all(a))-(a).begin())
#define mem(a,b) memset((a),(b),sizeof(a))
#define sz(x) (int((x).size()))
#define lowbit(x) ((x)&(-x))
#define lch p<<1,l,mid
#define rch p<<1|1,mid+1,r
#define ll (p<<1)
#define rr (p<<1|1)
#define queues priority_queue
#define pb push_back
#define mp(a,b) make_pair((a),(b))
#define lb lower_bound
#define ub upper_bound
#define ff first
#define ss second
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//__attribute__((optimize("-O2")))
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<bool> VB;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VII;
typedef vector<PLL> VLL;
// STL other **************************************************************************************
template<class T,class U>inline istream& operator >> (istream& os,pair<T,U>& p) { return os>>p.first>>p.second; }
template<class T,class U>inline pair<T,U> operator + (const pair<T,U>& p1,const pair<T,U>& p2) { return mp(p1.ff+p2.ff,p1.ss+p2.ss); }
template<class T,class U>inline pair<T,U>& operator += (pair<T,U>& p1,const pair<T,U>& p2) { p1.ff+=p2.ff,p1.ss+=p2.ss; return p1; }
template<class T,class U>inline pair<T,U> operator - (const pair<T,U>& p1,const pair<T,U>& p2) { return mp(p1.ff-p2.ff,p1.ss-p2.ss); }
template<class T,class U>inline pair<T,U>& operator -= (pair<T,U>& p1,const pair<T,U>& p2) { p1.ff-=p2.ff,p1.ss-=p2.ss; return p1; }
// Useful constants *******************************************************************************
const int primes[7] = {24443, 100271, 1000003, 1000333, 5000321, 98765431, 1000000123};
const int dx[]= { 0, 1, 0,-1, 0, 1,-1, 1,-1};
const int dy[]= {-1, 0, 1, 0,-1, 1,-1,-1, 1};
#define ee 2.718281828459
#define eps 0.00000001
#define fftmod 998244353
#define INF 0x3f3f3f3f
#define LINF 0xfcfcfcfcfcfcfcfll
#define MOD 1000000007
#define pi 3.14159265358979323846l
int teble();
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
#ifndef ONLINE_JUDGE
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
teble();
return 0;
}
//***************************************************************
//***************************************************************
//***************************************************************
/**________________________code.begin_________________________**/
const int N=1e5+5;
int a[N],b[N],tot,ans[N];
PII p[N];
struct Edge_Node {
int head[N],cnt;
struct Edge { int to,next; } edge[N];
void init() { mem(head,0),cnt=1; }
void add(int u,int v) {
edge[cnt]={v,head[u]},head[u]=cnt++;
}
} E;
struct Dictionarie_Tree {
int tree[N<<5][3],top;
void init() { mem(tree[0],0),top=1; }
void ins(int x,int id) {
int rt,nxt,u,t;
for(rt=0,t=31;~t;rt=nxt,--t) {
nxt=tree[rt][u=x>>t&1];
if(!nxt)mem(tree[top],0),tree[rt][u]=nxt=top++;
tree[nxt][2]=id;
}
}
int query(int x,int l) {
int rt,nxt,u,t,ans=0;
for(rt=0,t=31;~t;rt=nxt,--t) {
u=x>>t&1,ans<<=1;
if((nxt=tree[rt][!u])&&tree[nxt][2]<=l)ans+=1;
else nxt=tree[rt][u];
}
return ans;
}
} D;
struct Node {
int id,x,l,r;
bool operator < (Node &m) const {
return l>m.l;
}
} node[N];
void init() {
E.init(),D.init(),tot=0;
}
void dfs(int x) {
p[x].ff=++tot,b[tot]=x;
for(int i=E.head[x];i;i=E.edge[i].next) {
dfs(E.edge[i].to);
}
p[x].ss=tot;
}
int teble() {
int n,q,x,y;
while(cin>>n>>q) {
init();
FOR(i,1,n)cin>>a[i];
FOR(i,2,n)cin>>x,E.add(x,i);
dfs(1);
FOR(i,1,q)cin>>x>>y,node[i]={i,y,p[x].ff,p[x].ss};
sort(node+1,node+n+1);
int s=n;
FOR(i,1,q) {
while(s>=node[i].l)D.ins(a[b[s]],s),--s;
ans[node[i].id]=D.query(node[i].x,node[i].r);
}
FOR(i,1,q)cout<<ans[i]<<endl;
}
return 0;
}
/**_________________________code.end__________________________**/
//***************************************************************
//***************************************************************
//***************************************************************
/****************************************************************
** **
** ********* ********* ******** ** ********* **
** ** ** ** ** ** ** **
** ** ** ** ** ** ** **
** ** ********* ******** ** ********* **
** ** ** ** ** ** ** **
** ** ** ** ** ** ** **
** ** ********* ******** ********* ********* **
** **
****************************************************************/
HDU 6191 Query on A Tree(字典树+离线)的更多相关文章
- HDU - 6191 Query on A Tree (可持久化字典树/字典树合并)
题目链接 题意:有一棵树,树根为1,树上的每个结点都有一个数字x.给出Q组询问,每组询问有两个值u,x,代表询问以结点u为根的子树中的某一个数与x的最大异或值. 解法一:dfs序+可持久化字典树.看到 ...
- HDU 6191 Query on A Tree(可持久化Trie+DFS序)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- [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 Query on A Tree(可持久化Trie)
题意 \(n\) 个点的有根树,根为 \(1\) .每个点有点权,有 \(q\) 个询问,每次询问以 \(u\) 为根的子树的点的点权中异或 \(x\) 所得的最大值是多少. 思路 求出整棵树的 \( ...
- HDU 6191 Query on A Tree ( 2017广西邀请赛 && 可持久化Trie )
题目链接 题意 : 给你一棵树.树上的每个点都有点权.之后有若干次问询.每次问询给出一个节点编号以及一个整数 X .问你以给出节点为根的子树中哪个节点和 X 异或最大.输出这个值 分析 : 看到这种树 ...
- ACM学习历程—HDU 5536 Chip Factory(xor && 字典树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. ...
- HDU:1251-统计难题(字典树模板,动态建树,静态建树)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memor ...
- HDU 4825 Xor Sum(01字典树入门题)
http://acm.hdu.edu.cn/showproblem.php?pid=4825 题意: 给出一些数,然后给出多个询问,每个询问要从之前给出的数中选择异或起来后值最大的数. 思路:将给出的 ...
- HDU 1247 Hat’s Words(字典树)
http://acm.hdu.edu.cn/showproblem.php?pid=1247 题意: 给出一些单词,问哪些单词可以正好由其他的两个单词首尾相连而成. 思路: 先将所有单独插入字典树,然 ...
随机推荐
- [转帖] 国产x86-海光禅定 2018年营收过亿?
中科曙光:全年业绩稳健,海光芯片营收过亿 X86服务器市场Intel占据绝对优势:X86处理器已经成为全球最广泛使用的处理器架构之一,尤其是在PC和服务器领域,其中在处理器市场的份额高达90%以上.中 ...
- MySQL_基础
## 数据库的基本概念 1. 数据库的英文单词: DataBase 简称 : DB 2. 什么数据库? * 用于存储和管理数据的仓库. 3. 数据库的特点: 1. 持久化存储数据的.其实数据库就是一个 ...
- 头大!RabbitMQ 和 Kafka 到底怎么选?
前言 开源社区有好多优秀的队列中间件,比如RabbitMQ和Kafka,每个队列都貌似有其特性,在进行工程选择时,往往眼花缭乱,不知所措. 对于RabbitMQ和Kafka,到底应该选哪个? Rabb ...
- @OneToMany 一对多 通过表之间的链接
https://blog.csdn.net/qq_38157516/article/details/80146547 一对多 一个人对多张卡,但是一张卡只能对应一个人,典型的一对多关系,下面就用One ...
- gRPC编译教程
windows平台的编译 一.编译openssl ① 安装perl(可以使用ActivePerl),执行perl Configure VC-WIN64A no-asm .在这里解释一下参数含义,VC- ...
- P1106 删数问题
展开 题目描述 键盘输入一个高精度的正整数NN(不超过250250位) ,去掉其中任意kk个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的NN和kk,寻找一种方案使得剩下的数字组成的新 ...
- RabbitMQ入门教程(十):队列声明queueDeclare
原文:RabbitMQ入门教程(十):队列声明queueDeclare 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:// ...
- Git小结---So far.......
基本的: 1. 在配置了SSH Key的情况下,clone项目时使用:git clone git@github.com/用户名/仓库名.git 使用这种方式而不使用https的方式的好处在于,在pu ...
- Android中res下anim和animator文件夹区别与总结
1.anim文件夹 anim文件夹下存放tween animation(补间动画)和frame animation(逐帧动画) 逐帧动画: ①在animation-list中使用item定义动画的全部 ...
- leetcode957. N 天后的牢房
8 间牢房排成一排,每间牢房不是有人住就是空着. 每天,无论牢房是被占用或空置,都会根据以下规则进行更改: 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用. 否则,它就会被空置. ...