BZOJ3689: 异或之

题解:

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

然后本题做法

类似于超级钢琴。

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

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

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

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

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 100000+5
14 #define maxm 4000000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
22 #define mod 1000000007
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 typedef pair<int,pair<int,int> > pa;
32 priority_queue<pa,vector<pa>,greater<pa> >q;
33 int n,m,tot,a[maxn],t[maxm][2],s[maxm];
34 inline void add(int x)
35 {
36     int now=1;s[now]++;
37     for3(i,30,0)
38     {
39         int j=x>>i&1;
40         if(!t[now][j])t[now][j]=++tot;
41         now=t[now][j];
42         s[now]++;
43     }
44 }
45 inline int query(int x,int k)
46 {
47     int now=1,ans=0;
48     for3(i,30,0)
49     {
50         int j=x>>i&1;
51         if(k<=s[t[now][j]])now=t[now][j];
52         else
53         {
54             k-=s[t[now][j]];
55             ans|=1<<i;
56             now=t[now][j^1];
57         }
58     }
59     return ans;
60 }
61 int main()
62 {
63     freopen("input.txt","r",stdin);
64     freopen("output.txt","w",stdout);
65     n=read();m=read();tot=1;
66     for1(i,n)add(a[i]=read());
67     for1(i,n)q.push(make_pair(query(a[i],2),make_pair(a[i],2)));
68     for1(i,2*m)
69     {
70         int x=q.top().first,y=q.top().second.first,k=q.top().second.second;
71         if(i&1){if(i!=1)printf(" ");printf("%d",x);}
72         q.pop();
73         q.push(make_pair(query(y,k+1),make_pair(y,k+1)));
74     }
75     return 0;
76 }
View Code

 T_T没想到改成一个pair居然还慢了

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 100000+5
14 #define maxm 4000000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
22 #define mod 1000000007
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 typedef pair<int,int>pa;
32 priority_queue<pa,vector<pa>,greater<pa> >q;
33 int n,m,tot,a[maxn],b[maxn],t[maxm][2],s[maxm];
34 inline void add(int x)
35 {
36     int now=1;s[now]++;
37     for3(i,30,0)
38     {
39         int j=x>>i&1;
40         if(!t[now][j])t[now][j]=++tot;
41         now=t[now][j];
42         s[now]++;
43     }
44 }
45 inline int query(int x,int k)
46 {
47     int now=1,ans=0;
48     for3(i,30,0)
49     {
50         int j=x>>i&1;
51         if(k<=s[t[now][j]])now=t[now][j];
52         else
53         {
54             k-=s[t[now][j]];
55             ans|=1<<i;
56             now=t[now][j^1];
57         }
58     }
59     return ans;
60 }
61 int main()
62 {
63     freopen("input.txt","r",stdin);
64     freopen("output.txt","w",stdout);
65     n=read();m=read();tot=1;
66     for1(i,n)add(a[i]=read());
67     for1(i,n)q.push(make_pair(query(a[i],b[i]=2),i));
68     for1(i,2*m)
69     {
70         int x=q.top().first,y=q.top().second;
71         if(i&1){if(i!=1)printf(" ");printf("%d",x);}
72         q.pop();
73         q.push(make_pair(query(a[y],++b[y]),y));
74     }
75     return 0;
76 }
View Code

 

3689: 异或之

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

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小的数。

posted @ 2014-12-20 20:53  ZYF-ZYF  Views(322)  Comments(0Edit  收藏  举报