zoukankan      html  css  js  c++  java
  • BZOJ3689: 异或之

    题解:类似与超级钢琴的做法 直接用堆维护即可  (

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int n,k,cnt;
    int a[MAXN],rt[MAXN],tag[MAXN*32];
    typedef struct node{
        int l,r,sum;
    }node;
    node d[MAXN*32];
    void insert(int x,int k,int id){
        for(int i=30;i>=0;i--){
            if(k&(1<<i)){
                int t=++cnt;d[t]=d[d[x].r];d[x].r=t;d[t].sum++;
                x=t;
            }
            else{
                int t=++cnt;d[t]=d[d[x].l];d[x].l=t;d[t].sum++;
                x=t;
            }
        }
        tag[x]=id;
    }
    pair<int,int> querty(int x,int y,int k){
        int res=0;
        for(int i=30;i>=0;i--){
            if(k&(1<<i)){
                if(d[d[y].r].sum-d[d[x].r].sum)res+=(1<<i),x=d[x].r,y=d[y].r;
                else x=d[x].l,y=d[y].l;
            }
            else{
                if(d[d[y].l].sum-d[d[x].l].sum)x=d[x].l,y=d[y].l;
                else res+=(1<<i),x=d[x].r,y=d[y].r;
            }
        }
        res^=k;
        return mp(tag[y],res);
    }
    typedef struct Tmp{
        int pos,l,r,key,aim;
        friend bool operator<(Tmp aa,Tmp bb){return aa.key>bb.key;}
    }Tmp;
    priority_queue<Tmp>que;
    vector<int>vec;
    int main(){
        n=read();k=read();cnt=0;
        rt[0]=++cnt;insert(rt[0],0,0);
        inc(i,1,n)a[i]=read(),rt[i]=++cnt,d[rt[i]]=d[rt[i-1]],insert(rt[i],a[i],i);
        inc(i,2,n){
            pair<int,int> t=querty(rt[0],rt[i-1],a[i]);
            que.push((Tmp){t.first,1,i-1,t.second,i});
        }
        pair<int,int> t1;
        for(int i=1;i<=k;i++){
            vec.pb((que.top()).key);
            Tmp t=que.top();que.pop();printf("%d ",t.key);
            if(t.pos>t.l)t1=querty(rt[t.l-1],rt[t.pos-1],a[t.aim]),que.push((Tmp){t1.first,t.l,t.pos-1,t1.second,t.aim});
            if(t.pos<t.r)t1=querty(rt[t.pos],rt[t.r],a[t.aim]),que.push((Tmp){t1.first,t.pos+1,t.r,t1.second,t.aim});
        }
    }
    

      

    3689: 异或之

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 550  Solved: 269
    [Submit][Status][Discuss]

    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

  • 相关阅读:
    28、列举常见的内置函数(各个函数的示例,一大半没写全,慢慢更新,会全的)
    Django之前端插件定制之表头
    26、Python的可变类型和不可变类型?
    25、Python垃圾回收机制?
    24、简述Python的深浅拷贝以及应用场景
    基础题(五)
    使用OpenCV和Python进行人脸识别
    Codeforces Round #253 (Div. 2)B(暴力枚举)
    uva11609(组合数学,快速幂)
    uva10892(暴力枚举)
  • 原文地址:https://www.cnblogs.com/wang9897/p/9723096.html
Copyright © 2011-2022 走看看