Xor Sum HDU
阿新 • • 發佈:2018-12-16
求異或最大值
因為最近再刷字典樹,所以直接想到一個樹形方法(ˉ▽ˉ;)...
1.把每個數字的二進位制表示式當作一個字串插入字典樹中
2.
(1).從頂節點開始,和要求的數val的最大位數開始(第32位開始)
(2).根據當前節點now,和當前位數k,找出下一節點(如果有與該位不同的邊走則走那條邊,否則走與此位相同的邊),並賦給 now
(3).讓k--,並找出當前位數的位元值
(4).返回(2) ,直至k=0退出
3.記下路徑
4.求出異或最大值就OK
程式碼:
#include<stdio.h> #include<iostream> #include<string.h> #include<string> using namespace std; const int maxn=5000000; typedef struct Tire_Node { // int cnt; int net[2]; Tire_Node() { // cnt=0; for(int i=0; i<2; ++i) net[i]=-1; } void clear() { // cnt=0; for(int i=0; i<2; ++i) net[i]=-1; } } node; node nodearr[maxn]; int nodetop; int ans[50]; int Get_bit(int n,int k) { if(n&(1<<(k-1))) return 1; return 0; } void Become_bit(int &val,int k,int bit) { if(bit) val=val|(1<<(k-1)); else val=val&(~(1<<(k-1))); } void insert_node(int n) { int flag; int now=0; for(int i=32;i;--i) { flag=Get_bit(n,i); if(nodearr[now].net[flag]==-1) { nodearr[now].net[flag]=++nodetop; } now=nodearr[now].net[flag]; } } void clear_node(int num) { for(int i=0;i<=num;++i) nodearr[i].clear(); } int bfs(int now,int b_val,int k)// 在now節點下面 根據自己的位數v_bal,找到第k位 { if(~nodearr[now].net[b_val?0:1]) { ans[k]=b_val?0:1; return nodearr[now].net[b_val?0:1]; } else { ans[k]=b_val; return nodearr[now].net[b_val]; } } void Slove(int val)//求字典樹中與val 異或最大的值 { int now=0; for(int i=32;i>=1;--i) now=bfs(now,Get_bit(val,i),i); } int main() { int t,n,m,val,times=0,res; scanf("%d",&t); while(t--) { nodetop=0; scanf("%d %d",&n,&m); for(int i=0;i<n;++i) { scanf("%d",&val); insert_node(val); } printf("Case #%d:\n",++times); while(m--) { scanf("%d",&val); Slove(val); for(int i=1;i<=32;++i) Become_bit(res,i,ans[i]); printf("%d\n",res); } clear_node(nodetop); } }