您的位置:首页 > 其它

BZOJ3689: 异或之

2014-12-20 20:53 411 查看
题解:

首先知道一点trie不仅可以求与某个数异或的最大值.最小值,还能求第k大值,不能再神,orz!!!多添加一个size域即可。

然后本题做法

类似于超级钢琴。

我们先求出每个a[i]的第二异或最小值,然后放进堆里(第一是和自己)

然后我们往外取最小值,每次取出一个之后a[i]的第k小异或值就压入a[i]的第k+1小异或值。

正确性显然。输出的时候注意重复的。

代码:写pair套pair感觉很舒爽

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 100000+5
#define maxm 4000000+5
#define eps 1e-10
#define ll long long
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
typedef pair<int,int>pa;
priority_queue<pa,vector<pa>,greater<pa> >q;
int n,m,tot,a[maxn],b[maxn],t[maxm][2],s[maxm];
inline void add(int x)
{
int now=1;s[now]++;
for3(i,30,0)
{
int j=x>>i&1;
if(!t[now][j])t[now][j]=++tot;
now=t[now][j];
s[now]++;
}
}
inline int query(int x,int k)
{
int now=1,ans=0;
for3(i,30,0)
{
int j=x>>i&1;
if(k<=s[t[now][j]])now=t[now][j];
else
{
k-=s[t[now][j]];
ans|=1<<i;
now=t[now][j^1];
}
}
return ans;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();m=read();tot=1;
for1(i,n)add(a[i]=read());
for1(i,n)q.push(make_pair(query(a[i],b[i]=2),i));
for1(i,2*m)
{
int x=q.top().first,y=q.top().second;
if(i&1){if(i!=1)printf(" ");printf("%d",x);}
q.pop();
q.push(make_pair(query(a[y],++b[y]),y));
}
return 0;
}


View Code

3689: 异或之

Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 63 Solved: 34
[Submit][Status]

Description

给定n个非负整数A[1], A[2], ……, A

对于每对(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小的数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: