# 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

#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
//__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 {
struct Edge { int to,next; } edge[N];
}
} 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;
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];
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__________________________**/
//***************************************************************
//***************************************************************
//***************************************************************
/****************************************************************
**                                                             **
**  *********   *********   ********    **          *********  **
**      **      **          **     **   **          **         **
**      **      **          **     **   **          **         **
**      **      *********   ********    **          *********  **
**      **      **          **     **   **          **         **
**      **      **          **     **   **          **         **
**      **      *********   ********    *********   *********  **
**                                                             **
****************************************************************/

posted @ 2018-04-26 15:05  韵祈  阅读(...)  评论(...编辑  收藏