zeus 和 prometheus 做了乙個遊戲,prometheus 給 zeus 乙個集合,集合中包含了n個正整數,隨後 prometheus 將向 zeus 發起m次詢問,每次詢問中包含乙個正整數 s ,之後 zeus 需要在集合當中找出乙個正整數 k ,使得 k 與 s 的異或結果最大。prometheus 為了讓 zeus 看到人類的偉大,隨即同意 zeus 可以向人類求助。你能證明人類的智慧型麼?
input輸入包含若干組測試資料,每組測試資料報含若干行。
輸入的第一行是乙個整數t(t < 10),表示共有t組資料。
每組資料的第一行輸入兩個正整數n,m(<1=n,m<=100000),接下來一行,包含n個正整數,代表 zeus 的獲得的集合,之後m行,每行乙個正整數s,代表 prometheus 詢問的正整數。所有正整數均不超過2^32。output對於每組資料,首先需要輸出單獨一行」case #?:」,其中問號處應填入當前的資料組數,組數從1開始計算。
對於每個詢問,輸出乙個正整數k,使得k與s異或值最大。sample input
2sample output3 23 4 515
4 14 6 5 6
3
case #1:43case #2:
4題目分析 : 給你一堆數,一些詢問,問當前輸入的數同上面的哪個數異或值最大
思路分析 : 對於當前輸入的 n ,我們很容易判斷出其與哪個數異或的值最大,當然這個數不一定出現在上來的一堆數中,在這裡字典樹搞一下就很方便了
不是很懂的地方就是字典樹用陣列寫記憶體應該開多大的。
**示例 :
#define ll long longconst int maxn = 1e5+5;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
int pre[maxn][40];
int arr[maxn];
int len;
int tree[maxn*100][2];
int ans[50];
void init()
void fun(int x)
int k = len;
while(!que.empty())
}int rt = 1;
void build(int x)
}int pp[50];
int an;
void query()
//else
if (!tree[u][v]) v ^= 1;
u = tree[u][v];
an += v*ans[len-i];
//printf("an = %d v = %d \n", an, v);
}}int main()
len = floor(log(ma)/log(2))+1;
//printf("len = %d\n", len);
memset(pre, 0, sizeof(pre));
memset(tree, 0, sizeof(tree));
rt = 1;
for(int i = 1; i <= n; i++)
//for(int i = 1; i <= n; i++)
//printf("\n");
//}printf("case #%d:\n", kase++);
while(m--)
if (lenth >= len)
}else
}for(int i = 1; i <= len; i++) pp[i] ^= 1;
//for(int i = 1; i <= len; i++) printf("%d ", pp[i]);
//printf("\n");
query();
printf("%d\n", an);} }
return 0;
}
HDU6059(01字典樹求異或最大值)
題意 求a中 三個數a i,aj ak,ai a j ak i j這裡要動態維護字典樹,每當輸入乙個數,就更新一下字典樹。最後減去i j的情況 這裡最難懂 搞了好久,算是會了,手撕 時問題百出,還是沒有學到骨子裡,留下以後在複習。參看了兩位大佬的部落格 大佬部落格 小老部落格 include inc...
初試01字典樹(求異或問題)
題目鏈結 一般01字典樹用來解決區間異或和之類的問題。異或的性質 1.交換律 2.結合律,即 a b c a b c 3.自反性,即x x 0 4.x 0 x 其中運用最多的就是自反性。有上述性質,對於區間異或和要知道如下性質 xor l,r xor 1,l 1 xor 1,r 在查詢最大異或值時我...
最大異或(字典樹應用)
乙個字典樹與異或運算的集合。當時寫超時了,不知道為什麼。先記錄下來 題目 zeus 和 prometheus 做了乙個遊戲,prometheus 給 zeus 乙個集合,集合中包含了n個正整數,隨後 prometheus 將向 zeus 發起m次詢問,每次詢問中包含乙個正整數 s 之後 zeus 需...