bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338
题面:
5338: [TJOI2018]xor
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 269 Solved: 171
[Submit][Status][Discuss]
Description
现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi。
现在有Q 次操作,操作如下:
1 x y 查询节点x的子树中与y异或结果的最大值
2 x y z 查询路径x到y上点与z异或结果最大值
Input
第一行是两个数字n, Q;
第二行是n个数字用空格隔开,第i个数字vi表示点i上的权值
接下来n-1行,每行两个数,x,y,表示节点x与y之间有边
接下来Q行,每一行为一个查询,格式如上所述.
1 < n, Q ≤ 100000 ,查询1中的y ≤ 2^30 ,查询2中的z ≤ 2^30
Output
对于每一个查询,输出一行,表示满足条件的最大值。
Sample Input
7 5
1 3 5 7 9 2 4
1 2
1 3
2 4
2 5
3 6
3 7
1 3 5
2 4 6 3
1 5 5
2 5 7 2
1 1 9
1 3 5 7 9 2 4
1 2
1 3
2 4
2 5
3 6
3 7
1 3 5
2 4 6 3
1 5 5
2 5 7 2
1 1 9
Sample Output
7
6
12
11
14
6
12
11
14
实现代码;
#include<bits/stdc++.h> using namespace std; const int M = 2e5+10; struct node{ int to,next; }e[M]; int cnt,cnt1,n; int son[M],siz[M],head[M],fa[M],top[M],dep[M],tid[M],mx[M],rk[M]; void add(int u,int v){ e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt; } void dfs1(int u,int faz,int deep){ dep[u] = deep; fa[u] = faz; siz[u] = 1; for(int i = head[u];i;i = e[i].next){ int v = e[i].to; if(v == faz) continue; dfs1(v,u,deep+1); siz[u] += siz[v]; if(siz[v] > siz[son[u]]||son[u] == -1) son[u] = v; } } void dfs2(int u,int t){ top[u] = t; tid[u] = ++cnt1; mx[u] = cnt1; rk[cnt1] = u; if(son[u] == -1) return ; dfs2(son[u],t); for(int i = head[u];i;i=e[i].next){ int v = e[i].to; if(v != fa[u]&&v != son[u]) dfs2(v,v); } mx[u] = cnt1; } struct node1{ int s[2],v; }t[M*50]; int idx,rt[M]; void update(int &k,int p,int w){ t[++idx] = t[k]; k = idx; t[k].v++; if(w == -1) return ; if(p&(1<<w)) update(t[k].s[1],p,w-1); else update(t[k].s[0],p,w-1); } int query(int old,int k,int p,int w){ if(w == -1) return 0; int c= (bool)(p&(1<<w)); if(t[t[k].s[c^1]].v - t[t[old].s[c^1]].v) return query(t[old].s[c^1],t[k].s[c^1],p,w-1)|(1<<w); else return query(t[old].s[c],t[k].s[c],p,w-1); } int ask(int x,int y,int z){ int ans = 0; int fx = top[x],fy = top[y]; while(fx != fy){ if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy); ans = max(ans,query(rt[tid[fx]-1],rt[tid[x]],z,30)); x = fa[fx]; fx = top[x]; } if(dep[x] > dep[y]) swap(x,y); ans = max(ans,query(rt[tid[x]-1],rt[tid[y]],z,30)); return ans; } int a[M]; int main() { int n,q,u,v,x,y,z,op; scanf("%d%d",&n,&q); memset(son,-1,sizeof(son)); for(int i = 1;i <= n;i ++) scanf("%d",&a[i]); for(int i = 1;i < n;i ++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs1(1,0,1); dfs2(1,1); for(int i = 1;i <= n;i ++) rt[i]=rt[i-1],update(rt[i],a[rk[i]],30); while(q--){ scanf("%d%d%d",&op,&x,&y); if(op == 1){ printf("%d\n",query(rt[tid[x]-1],rt[mx[x]],y,30)); } else{ scanf("%d",&z); printf("%d\n",ask(x,y,z)); } } return 0; }