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


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?
 

Input
There are no more than 6 test cases.

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$
 

Output
For each query, just print an integer in a line indicating the largest result.
 

Sample Input
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(字典树+离线)的更多相关文章

  1. HDU - 6191 Query on A Tree (可持久化字典树/字典树合并)

    题目链接 题意:有一棵树,树根为1,树上的每个结点都有一个数字x.给出Q组询问,每组询问有两个值u,x,代表询问以结点u为根的子树中的某一个数与x的最大异或值. 解法一:dfs序+可持久化字典树.看到 ...

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

  3. [hdu 6191] Query on A Tree

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

  4. HDU 6191 Query on A Tree(可持久化Trie)

    题意 \(n\) 个点的有根树,根为 \(1\) .每个点有点权,有 \(q\) 个询问,每次询问以 \(u\) 为根的子树的点的点权中异或 \(x\) 所得的最大值是多少. 思路 求出整棵树的 \( ...

  5. HDU 6191 Query on A Tree ( 2017广西邀请赛 && 可持久化Trie )

    题目链接 题意 : 给你一棵树.树上的每个点都有点权.之后有若干次问询.每次问询给出一个节点编号以及一个整数 X .问你以给出节点为根的子树中哪个节点和 X 异或最大.输出这个值 分析 : 看到这种树 ...

  6. ACM学习历程—HDU 5536 Chip Factory(xor && 字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题目大意是给了一个序列,求(si+sj)^sk的最大值. 首先n有1000,暴力理论上是不行的. ...

  7. HDU:1251-统计难题(字典树模板,动态建树,静态建树)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memor ...

  8. HDU 4825 Xor Sum(01字典树入门题)

    http://acm.hdu.edu.cn/showproblem.php?pid=4825 题意: 给出一些数,然后给出多个询问,每个询问要从之前给出的数中选择异或起来后值最大的数. 思路:将给出的 ...

  9. HDU 1247 Hat’s Words(字典树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1247 题意: 给出一些单词,问哪些单词可以正好由其他的两个单词首尾相连而成. 思路: 先将所有单独插入字典树,然 ...

随机推荐

  1. hbase部署

    Hbase: 更细的操作和原理研究笔记和视频 cloudera Hbase:https://sysit.cn/blog/post/sysit/cloudera%E5%AE%89%E8%A3%85HBA ...

  2. PTA(Basic Level)1013.数素数

    令 *P**i* 表示第 i 个素数.现任给两个正整数 M≤N≤104,请输出 *P**M* 到 *P**N* 的所有素数. 输入格式: 输入在一行中给出 M 和 N,其间以空格分隔. 输出格式: 输 ...

  3. MySQL -2- 体系结构-多实例模块

    0.在已创建mysql,port=3306的数据库前提下 需要删除/etc/.my.cnf再做以下操作 cp /etc/my.cnf /etc/my.cnf.3306 1.mkdir -p /u02/ ...

  4. 史上最详细 Linux 用户与用户组知识

    1.用户和用户组文件 在 linux 中,用户帐号,用户密码,用户组信息和用户组密码均是存放在不同的配置文件中的. 在 linux 系统中,所创建的用户帐号和其相关信息 (密码除外) 均是存放在 / ...

  5. 【转】iptables命令、规则、参数详解

    表    (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...

  6. Who will be punished

    Who will be punished Problem Description This time,suddenly,teacher Li wants to find out who have mi ...

  7. 利用pcl数据结构,实现RegionGrowing的复现

    这篇博客是pcl中区域增长的算法进行简介以实现重写,并添加了一些判断条件. 起初原因是在使用pcl封装的regionGrowing时,效果不太好. 于是想自己重新写一下,通过改变其中种子点的生成策略和 ...

  8. git 版本回退方法

    ORIG_HEAD 某些操作,例如 merage / reset 会把 merge 之前的 HEAD 保存到 ORIG_HEAD 中,以便在 merge 之后可以使用 ORIG_HEAD 来回滚到合并 ...

  9. 用 C++ 模板元编程实现有限的静态 introspection

    C++ 中的奇技淫巧大部分来源于模板技术,尤其是模版元编程技术(Template Meta-Programming, TMP).TMP 通过将一部分计算任务放在编译时完成,不仅提高了程序的性能,还能让 ...

  10. String与C风格字符串转换

    String字符串转换为C风格字符串需要利用string类的成员函数c_str().而C风格字符串转换转换为string字符串可以直接利用运算符=.首先介绍c_str()函数原型: const val ...