BZOJ3689: 异或之
2014-12-20 20:53
411 查看
题解:
首先知道一点trie不仅可以求与某个数异或的最大值.最小值,还能求第k大值,不能再神,orz!!!多添加一个size域即可。
然后本题做法
类似于超级钢琴。
我们先求出每个a[i]的第二异或最小值,然后放进堆里(第一是和自己)
然后我们往外取最小值,每次取出一个之后a[i]的第k小异或值就压入a[i]的第k+1小异或值。
正确性显然。输出的时候注意重复的。
代码:写pair套pair感觉很舒爽
View Code
Submit: 63 Solved: 34
[Submit][Status]
。
对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n-1)/2个新的数。求这些数(不包含A[i])中前k小的数。
注:xor对应于pascal中的“xor”,C++中的“^”。
以下n行,每行一个非负整数表示A[i]。
首先知道一点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 MBSubmit: 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小的数。相关文章推荐
- BZOJ_3689_异或之_可持久化Trie+堆
- BZOJ[3689] 异或之 Trie树+堆
- bzoj 3689 异或之
- BZOJ3689 异或之
- BZOJ 3689 异或之
- BZOJ 3689 异或之
- [乱搞 || 可持久化字典树 堆] BZOJ3689 异或之
- bzoj 3689: 异或之 Trie+堆
- [Trie树] BZOJ3689: 异或之
- 【bzoj3689】异或之 trie+堆
- [BZOJ 3689]异或之
- bzoj 3689: 异或之
- BZOJ 3689: 异或之 字典树 优先队列
- BZOJ3689 异或之
- bzoj 3689: 异或之 字典树+堆
- BZOJ 3689 异或之
- 【bzoj3689】异或之 可持久化Trie树+堆
- 【bzoj3689】【异或之】【trie树+堆】
- 【BZOJ3689】异或之 堆+可持久化Trie树
- BZOJ 3689: 异或之