3689: 异或之
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 262 Solved: 120[][][]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 5 1 1 3 4
Sample 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{250000, n*(n-1)/2}; 0 <= A[i] < 2^31
Source
#include#include using namespace std;int read(){ register int x=0;bool f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=0;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return f?x:-x;}const int N=1e5+10;struct node{ int a,v,k; bool operator <(const node &t)const{ return v>t.v; }}z;priority_queue q;int n,m,K,cnt,a[N],siz[N*31],tr[N*31][2];void ins(int x){ int now=0; for(int i=30;i>=0;i--){ int t=x&(1< >=i; if(!tr[now][t]) tr[now][t]=++cnt; now=tr[now][t];siz[now]++; }}int query(int x,int k){ int now=0,ans=0; for(int i=30;i>=0;i--){ int t=x&(1< >=i; if(siz[tr[now][t]]>=k) now=tr[now][t]; else k-=siz[tr[now][t]],now=tr[now][t^1],ans+=(1<