Title Description
answer
EDITORIAL
Yi (yì) or tree XOR tree
Pre-knowledge
To solve this problem, you should be
- Trie tree template
- Trie tree binary representation of the number
Thinking
Solution 1
I'll be violent!
Under the worst case time complexity of \ (O (nm) \)
Score: \ (29 \) points
Good water ah
Solution of water
I will Trie tree!
All the pre-sub-tree and XOR, join the Trie, direct binary search.
Score: \ (0 \) points
This thing tells us easy violent than fucks
Solution 2
I will modify the Trie template!
This problem was observed and found difficulty is how to present title \ (O (logx) \) is obtained in the subtree rooted at u a sub-tree of XOR and
After thinking can be found in the Trie tree select the node corresponding to each node is given the title of record in the Trie, then LCA \ (O (logN) \) queries whether there is ancestral relationship to
However, when all the nodes of the tree and subtrees are the same or different each node corresponding to the Trie given subject can reach \ (n-\) , the total time complexity is \ (O (m logx n logn ) \ )
score: \ (29 \) points
Solution 3
I will be offline processing!
Since \ (n-m = \) , so the interrogation points or substantially covers the entire tree, there are many duplicate or
So that it can consider the leaf node is obtained, then layer by layer will shift Trie tree
which is to find the Trie son nodes, the nodes have been processed asked his son, then one son node in the Trie extended to his father Trie tree (i.e., the addition of other child nodes parent node), this step is repeated
Thus, when asked point or basically covered the whole tree, expansion would be more efficient, when repeated many, many times higher processing efficiency, but the worst time complexityIt seems a bit difficult to estimate
DETAILED algorithm steps
(hereinafter referred to as a consultant node interrogating node)
1. pretreatment
2. Locate the interrogating node u
3. For each query node u, first find the largest number of child nodes inquiry asking the subtree of node u v subtree node
subtree of node u 4. interrogation and other query node added in the Trie node v
5. interrogation query all of the processing node u
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,a[100005],x[100005],s[100005],d[100005];
struct que {
int x,id;
} ans[100005];
vector<que>q[100005];
vector<int>g[100005];
void dfs(int u,int fa) {//步骤1
s[u]=1,x[u]=a[u];
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
dfs(v,u);
s[u]=s[u]+s[v],x[u]=x[u]^x[v];
}
}
struct trie {
vector<int*>c;
int tot;
void build() {
tot=0;
c.clear(),c.push_back(NULL);
}
void insert(int x) {
int p=0;
for(int i=30; i>=0; i--) {
int v=((x&(1<<i))>>i);
if(c[p]==NULL) {
c[p]=new int[2];
memset(c[p],-1,sizeof(int)*2);
}
if(c[p][v]==-1) {
c[p][v]=++tot;
c.push_back(NULL);
}
p=c[p][v];
}
}
int find(int x) {
int p=0;
for(int i=30; i>=0; i--) {
int v=((x&(1<<i))>>i);
if(c[p][v^1]==-1)p=c[p][v];
else p=c[p][v^1],x=(x^(1<<i));
}
return x;
}
} tr[100005];
int b,t,y;
void xun(int u,int fa) {//步骤3
if(q[u].size()>0) {
if(s[u]>s[b])b=u;
return;
}
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
xun(v,u);
}
}
void zhao(int u,int fa) {//步骤4
if(u==b)return;
tr[y].insert(x[u]);
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
zhao(v,u);
}
}
void check(int u,int fa) {//步骤2
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
check(v,u);
}
if(q[u].size()>0) {
b=0;//步骤3
for(int i=0; i<g[u].size(); i++) {
int v=g[u][i];
if(v==fa)continue;
xun(v,u);
}
if(b==0)d[u]=t++,tr[d[u]].build();
else d[u]=d[b];
y=d[u];
zhao(u,fa);//步骤4
}
for(int i=0; i<q[u].size(); i++) {//步骤5
ans[m].id=q[u][i].id;
ans[m--].x=q[u][i].x^tr[d[u]].find(q[u][i].x);
}
}
bool cmp(que a1,que b1) {
return a1.id<b1.id;
}
inline int read() {
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9') {
s=s*10+ch-'0';
ch=getchar();
}
return s;
}
int main() {
n=read(),m=read();
for(int i=1; i<=n; i++)a[i]=read();
for(int i=1; i<n; i++) {
int u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=1; i<=m; i++) {
int u=read(),x=read();
q[u].push_back((que){x,i});
}
dfs(1,0);
check(1,-1);
sort(ans+1,ans+1+n,cmp);
for(int i=1; i<=n; i++)printf("%d\n",ans[i].x);
return 0;
}