1. 程式人生 > >【HDU 6191】Query on A Tree 【可持久化字典樹】

【HDU 6191】Query on A Tree 【可持久化字典樹】

algorithm stream %d ons turn class img cstring str

題目

給出一棵有n個結點的樹,樹根是1,每個結點給出一個value。然後給出q個詢問,每個詢問給出兩個整數u和x,你要在以u結點為根的子樹中找出一個結點v,使得val[v] xor x最大, 並輸出這個最大值

分析

顯而易見的可持久化字典樹,只不過這次每次查詢不是查詢一個區間,而是查詢一棵子樹。那麽也很簡單,我們只要預處理出dfs序然後找出每個結點以它為根的子樹在dfs序中的區間。然後以這個區間建可持久化字典樹就可以了。

技術分享圖片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4
#include <algorithm> 5 6 using namespace std; 7 const int maxn=100000+10; 8 int val[maxn]; 9 int head[maxn],to[maxn],Next[maxn]; 10 int n,q,sz; 11 void add_edge(int a,int b){ 12 ++sz; 13 to[sz]=b;Next[sz]=head[a];head[a]=sz; 14 } 15 int order[maxn],L[maxn],R[maxn],num; 16 void
dfs(int u,int fa){ 17 num++; 18 order[num]=val[u]; 19 L[u]=num; 20 for(int i=head[u];i!=-1;i=Next[i]){ 21 int v=to[i]; 22 if(v!=fa) 23 dfs(v,u); 24 } 25 R[u]=num; 26 } 27 int ch[maxn*2*33][2],root[maxn],sum[maxn*2*33][2],cnt,val_t[2*maxn*33
]; 28 void update(int x,int y,int a,int ID){ 29 root[x]=++cnt;x=root[x]; 30 for(int i=31;i>=0;i--){ 31 int id=(a>>i)&1; 32 sum[x][id]+=sum[y][id]+1; 33 sum[x][!id]+=sum[y][!id]; 34 ch[x][!id]=ch[y][!id]; 35 ch[x][id]=++cnt; 36 memset(ch[cnt],0,sizeof(ch[cnt])); 37 val_t[cnt]=0; 38 x=ch[x][id];y=ch[y][id]; 39 } 40 val_t[x]=ID; 41 } 42 int query(int x,int y,int a){ 43 for(int i=31;i>=0;i--){ 44 int id=(a>>i)&1; 45 if(sum[x][!id]-sum[y][!id]){ 46 x=ch[x][!id],y=ch[y][!id]; 47 }else{ 48 x=ch[x][id],y=ch[y][id]; 49 } 50 } 51 return val_t[x]; 52 } 53 int main(){ 54 while(scanf("%d%d",&n,&q)!=EOF){ 55 sz=0; 56 cnt=0; 57 memset(head,-1,sizeof(head)); 58 memset(sum,0,sizeof(sum)); 59 for(int i=1;i<=n;i++){ 60 scanf("%d",&val[i]); 61 } 62 for(int i=2;i<=n;i++){ 63 int a; 64 scanf("%d",&a); 65 add_edge(a,i); 66 } 67 num=0; 68 dfs(1,-1); 69 // for(int i=1;i<=n;i++) 70 // printf("%d ",order[i]); 71 // printf("\n"); 72 update(0,0,0,0); 73 for(int i=1;i<=n;i++){ 74 update(i,root[i-1],order[i],i); 75 } 76 int u,x; 77 for(int i=1;i<=q;i++){ 78 scanf("%d%d",&u,&x); 79 printf("%d\n",order[query(root[R[u]],root[L[u]-1],x)]^x); 80 } 81 } 82 return 0; 83 }
View Code

【HDU 6191】Query on A Tree 【可持久化字典樹】