zoukankan      html  css  js  c++  java
  • 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小的数。

  • 相关阅读:
    bootstrap 按钮 文本 浮动 隐藏
    bootstrap 表单控件 控件状态 控件大小 help-block
    wps 操作
    SSH中的免password登录
    Qt音乐播放器制作(二)Easy Player
    云计算资源分享与下载
    uva11059(最大乘积)
    两小时搞定C#版超级战舰游戏
    数据库中的參照完整性(Foreign Key)
    动手解决困扰自己的事情——记屏蔽网页广告
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4175840.html
Copyright © 2011-2022 走看看