Query on A Tree

时间限制: 8 Sec  内存限制: 512 MB
提交: 15  解决: 3
[提交][状态][讨论版]

题目描述

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?

输入

There are no more than six test cases.
For each test case there are two positive integers n(2 ≤ n ≤ 105) and q(2 ≤ q ≤ 105), indicating 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 V1, V2, ... , Vn(0 ≤ Vi ≤ 109), indicating the value of node i. The root of the tree is node 1.
The second line contains n-1 non-negative integers F1, F2,...Fn−1, Fi(1 ≤ Fi ≤ n) means the father of node i + 1.
And then q lines follow.
In the i-th line, there are two integers u(1 ≤ u ≤ n) and x(0 ≤ x ≤ 109), indicating that the node you pick should be in the subtree of u, and x has been described in the problem.

输出

 

样例输入

2 2
1 2
1
1 3
2 1

样例输出

2
3
【题意】给你一棵树,每个节点有权值,Q次询问,求u为跟的子树里与x亦或后的值最大是多少。
【分析】可持续化字典树可用来解决一段区间内与x亦或后的值最大是多少,这里可以用dfs序将子树转为序列。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 2e5+;;
const int M = ;
const int mod = 1e9+;
const int mo=;
const double pi= acos(-1.0);
typedef pair<int,int>pii; int bin[];
int n,m,tot;
int a[N],root[N],id[N],st[N],ed[N];
vector<int>edg[N];
struct trie{
int cnt;
int ch[N*][],sum[N*];
void init(){
met(ch,);met(sum,);
cnt=;
}
int insert(int x,int val){
int tmp,y;tmp=y=++cnt;
for(int i=;i>=;i--)
{
ch[y][]=ch[x][];ch[y][]=ch[x][];
sum[y]=sum[x]+;
int t=val&bin[i];t>>=i;
x=ch[x][t];
ch[y][t]=++cnt;
y=ch[y][t];
}
sum[y]=sum[x]+;
return tmp;
}
int query(int l,int r,int val){
int tmp=;
for(int i=;i>=;i--)
{
int t=val&bin[i];t>>=i;
if(sum[ch[r][t^]]-sum[ch[l][t^]])
tmp+=bin[i],r=ch[r][t^],l=ch[l][t^];
else r=ch[r][t],l=ch[l][t];
}
return tmp;
}
}trie;
void dfs(int u,int fa){
st[u]=++tot;
id[tot]=u;
for(int i=;i<edg[u].size();i++){
int v=edg[u][i];
if(v==fa)continue;
dfs(v,u);
}
ed[u]=tot;
}
int main(){
bin[]=;for(int i=;i<=;i++)bin[i]=bin[i-]<<;
while(~scanf("%d%d",&n,&m)){
root[]=;tot=;
trie.init();
for(int i=;i<=n;i++)scanf("%d",&a[i]),edg[i].clear();
for(int i=;i<=n;i++){
int v;
scanf("%d",&v);
edg[v].pb(i);
}
dfs(,);
for(int i=;i<=n;i++)root[i]=trie.insert(root[i-],a[id[i]]);
int l,r,x,u;
while(m--){
scanf("%d%d",&u,&x);
l=st[u];r=ed[u];
printf("%d\n",trie.query(root[l-],root[r],x));
}
}
return ;
}

最新文章

  1. html表单提交方式
  2. jQuery 取值、赋值的基本方法
  3. Flat UI
  4. ubuntu14.04配置静态IP地址
  5. asp.net 常用的几种调用存储过程的方法
  6. 纯javascript代码编写计算器程序
  7. angularjs 将带标签的内容解析后返回
  8. 说一说Servlet 的生命周期
  9. excel转化为Json
  10. bzoj-4318 OSU! 【数学期望】
  11. [SCOI2008]斜堆
  12. Centos7下使用Ceph-deploy快速部署Ceph分布式存储-操作记录
  13. Servlet 随记:
  14. 了解Git的工作区和暂存区
  15. HDU-4850 Wow! Such String! (构造)
  16. JavaScript学习知识点归纳
  17. Spring+微信小程序 卡券打通
  18. cocos2d-x 2.2 创建项目
  19. 【Git/GitHub学习笔记】基本操作——创建仓库,本地、远程同步等
  20. MVC使用Newtonsoft无需实体类,实现JSON数据返回给前端页面使用

热门文章

  1. mysql 多列唯一索引在事务中select for update是不是行锁?
  2. Eclipse代码报错提示: the import java.util cannot be resolve,怎么解决?
  3. UOJ#110. 【APIO2015】Bali Sculptures
  4. bzoj 1731: [Usaco2005 dec]Layout 排队布局 ——差分约束
  5. Maven整体认识——详细介绍
  6. 【洛谷 P1390】 公约数的和 (欧拉函数)
  7. python初步学习-python控制流
  8. arpspoof dnsspoof中间人攻击
  9. DTW 算法(转)
  10. sicily 数据结构 1014. Translation