給定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 <= a[i] < 2^31
直到英語劇都演完了還沒想出來
乙個直觀的想法就是按位貪心,我們只需要開一棵字典樹把所有數字插入就能logn統計第k異或小。同時記錄第i個數當前第id小的答案,每次取堆頂然後id++即可,非要說的話比較類似那個超級鋼琴
需要注意的是數對(x,y)的貢獻x^y只應該被算一次但是會被算兩次,因此每彈棧兩次才輸出一次答案
#include
#include
#include
#include
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
const
int n=100005;
int rec[n*40][2],size[n*40],tot=1;
int a[n];
struct data
} ;std:: priority_queue heap;
int read()
void ins(int x)
now=rec[now][ch];
size[now]++;
}}int ask(int x,int k)
int main(void)
rep(i,1,n) );
}for (int i=1;i2;i++) );
}return0;}
/*001
001011
100*/
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 先對所有數建一棵字典樹,對字典樹的每個節點記錄這個節點...
BZOJ 3689 異或之 Trie樹 堆
題目鏈結 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個正整數...
bzoj3689 異或之 trie 堆
好多種解法,自己yy了一種二分答案 trie的做法,不過貌似還是o nlog 2n 的,看了一下popoqqq大神的題解,發現可以用堆來做,先把每個位置的最小值放入堆裡,每次彈出乙個元素,假設這個元素是對應位置的第k小,那麼把對應位置的第k 1小放入堆中。乙個巧妙的處理,因為會重複,所以取2 k次,...