http://acm.hdu.edu.cn/showproblem.php?pid=4757
给出一棵树,每个节点有权值,每次查询节点 (u,v) 以及 val,问 u 到 v 路径上的某个节点与 val 异或最大的值是多少。
和可持久化线段树差不多,看代码吧。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<vector> 7 using namespace std; 8 #define LL long long 9 const int maxn=100010; 10 const int maxm=3000010; 11 int n,m; 12 int a[maxn]={},fa[maxn][20]={},dep[maxn]={},rt[maxn]={}; 13 int sig[maxm][2]={},sz[maxm]={},cnt=0; 14 struct nod{int y,next;}e[maxn*2];int head[maxn],tot=0; 15 inline void init(int x,int y){e[++tot].y=y;e[tot].next=head[x];head[x]=tot;} 16 inline int getnew(){ 17 sig[++cnt][0]=0;sig[cnt][1]=0; 18 sz[cnt]=0;return cnt; 19 } 20 inline void bui(int x,int pa,int val){ 21 rt[x]=getnew();pa=rt[pa]; 22 x=rt[x]; 23 for(int i=15;i>=0;--i){ 24 int ch=(val>>i)&1; 25 if(!sig[x][ch]){ 26 int id=getnew(); 27 sig[x][ch]=id; sig[x][!ch]=sig[pa][!ch]; 28 sz[sig[x][ch]]=sz[sig[pa][ch]]; 29 } 30 x=sig[x][ch];pa=sig[pa][ch]; 31 ++sz[x]; 32 } 33 } 34 void dfs(int x){ 35 bui(x,fa[x][0],a[x]); 36 for(int i=1;fa[x][i-1];++i)fa[x][i]=fa[fa[x][i-1]][i-1]; 37 for(int i=head[x];i;i=e[i].next){ 38 if(e[i].y==fa[x][0])continue; 39 fa[e[i].y][0]=x;dep[e[i].y]=dep[x]+1;dfs(e[i].y); 40 } 41 } 42 inline int getlca(int x,int y){ 43 if(dep[x]<dep[y])swap(x,y); 44 for(int i=19;i>=0;--i)if(dep[fa[x][i]]>=dep[y])x=fa[x][i]; 45 if(x==y)return x; 46 for(int i=19;i>=0;--i)if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];} 47 return fa[x][0]; 48 } 49 int Query(int x,int y,int val){ 50 int lc=getlca(x,y); int res=a[lc]^val; 51 x=rt[x];y=rt[y];lc=rt[lc]; 52 int ret=0; 53 for(int i=15;i>=0;--i){ 54 int ch=(val>>i)&1; 55 if(sz[sig[x][!ch]]+sz[sig[y][!ch]]-2*sz[sig[lc][!ch]]>0){ 56 ret+=1<<i; 57 ch=!ch; 58 } 59 x=sig[x][ch];y=sig[y][ch];lc=sig[lc][ch]; 60 } 61 return max(res,ret); 62 } 63 int main(){ 64 while(~scanf("%d%d",&n,&m)){ 65 memset(head,0,sizeof(head));memset(rt,0,sizeof(rt)); 66 memset(sig,0,sizeof(sig));memset(fa,0,sizeof(fa)); 67 int x,y,z;tot=0;cnt=0; 68 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 69 for(int i=1;i<n;i++){scanf("%d%d",&x,&y);init(x,y);init(y,x);} 70 dep[1]=1;dfs(1); 71 for(int i=1;i<=m;i++){ 72 scanf("%d%d%d",&x,&y,&z); 73 printf("%d ",Query(x,y,z)); 74 } 75 } 76 return 0; 77 }