題目鏈結
description
給定n個非負整數a[1], a[2], ……, a[n]。
對於每對(i, j)滿足1 <= i < j <= n,得到乙個新的數a[i] xor a[j],這樣共有n*(n-1)/2個新的數。求這些數(不包含a[i])中前k小的數。
注:xor對應於pascal中的「xor」,c++中的「^」。
input
第一行2個正整數 n,k,如題所述。
以下n行,每行乙個非負整數表示a[i]。
output
共一行k個數,表示前k小的數。
sample input
4 5sample output
0 2 2 5 5
hint
【樣例解釋】
1 xor 1 = 0 (a[1] xor a[2])
1 xor 3 = 2 (a[1] xor a[3])
1 xor 4 = 5 (a[1] xor a[4])
1 xor 3 = 2 (a[2] xor a[3])
1 xor 4 = 5 (a[2] xor a[4])
3 xor 4 = 7 (a[3] xor a[4])
前5小的數:0 2 2 5 5
【資料範圍】
對於100%的資料,2 <= n <= 100000; 1 <= k <= min;
0 <= a[i] < 2^31
trie樹+堆
可以對每乙個數的二進位制建一棵trie樹,這樣就可以通過每乙個節點的si
ze快速查詢出乙個數與其它數異或值的第
k 小
維護乙個小根堆,將每個數異或的第二小扔入堆中(第一小是它自己),表示是與這個數異或出的第二小的數,在取出堆頂的同時,則取出的數數可以看做與id
異或起來第nu
m 小的數被扔入堆中的,然後再將id
與其他數異或出的第(n
um+1
) 小的數再扔入堆中
然而這樣會有重複的答案,
a ^b和
b ^
a都會被記作答案,可以找出2∗
k 個數,肯定有一半是重複的,所以可以隔兩個一輸出即可
**如下:
#include
#include
#include
#define n 4000010
using
namespace
std;
const
int maxx=32;
int ch[n][2],size[n];
int a[n];
int top,n,m,k,ans,x;
struct elem
elem(){}
elem(int _,int __,int ___):w(_),id(__),num(___){}
};priority_queuevector
,greater> q;
void add(int t)
}int query(int id,int k)
return ans;
}int main()
return
0;}
bzoj3689 異或之 trie 堆
好多種解法,自己yy了一種二分答案 trie的做法,不過貌似還是o nlog 2n 的,看了一下popoqqq大神的題解,發現可以用堆來做,先把每個位置的最小值放入堆裡,每次彈出乙個元素,假設這個元素是對應位置的第k小,那麼把對應位置的第k 1小放入堆中。乙個巧妙的處理,因為會重複,所以取2 k次,...
bzoj 3689 異或之 字典樹 堆
給定n個非負整數a 1 a 2 a n 對於每對 i,j 滿足1 i j n,得到乙個新的數a i xor a j 這樣共有n n 1 2個新的數。求這些數 不包含a i 中前k小的數。2 n 100000 1 k min 0 a i 2 31 先對所有數建一棵字典樹,對字典樹的每個節點記錄這個節點...
bzoj3689 異或之 字典樹 堆
給定n個非負整數a 1 a 2 a n 對於每對 i,j 滿足1 i j n,得到乙個新的數a i xor a j 這樣共有n n 1 2個新的數。求這些數 不包含a i 中前k小的數。注 xor對應於pascal中的 xor c 中的 對於100 的資料,2 n 100000 1 k min 0 ...