zoukankan      html  css  js  c++  java
  • BZOJ_3689_异或之_可持久化Trie+堆

    BZOJ_3689_异或之_可持久化Trie+堆

    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


    类似超级钢琴那道题,只不过这道题需要求一个数和区间内某数异或的最小值。

    于是我们对前缀建立可持久化Trie,直接Trie树上贪心即可。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <ext/pb_ds/priority_queue.hpp>
    using namespace std;
    using namespace __gnu_pbds;
    #define N 100050
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        register int x=0; register char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    struct A {
        int x,p,l,r,v;
        A() {}
        A(int x_,int p_,int l_,int r_,int v_) :
            x(x_),p(p_),l(l_),r(r_),v(v_) {}
    };
    int a[N],n,K,end[N*35];
    inline bool operator < (const A &x,const A &y) {
        return x.v>y.v;
    }
    __gnu_pbds::priority_queue<A>q;
    int root[N],ch[N*35][2],siz[N*35],cnt=1;
    void insert(int k) {
        int i;
        root[k]=++cnt;
        int p=root[k],q=root[k-1];
        siz[p]=siz[q]+1;
        for(i=31;i>=1;i--) {
            int t=((a[k]>>(i-1))&1);
            ch[p][!t]=ch[q][!t];
            ch[p][t]=++cnt;
            p=ch[p][t];
            q=ch[q][t];
            siz[p]=siz[q]+1;
        }
        end[p]=k;
    }
    int query(int l,int r,int x) {
        int p=root[l-1],q=root[r],i,pos;
        for(i=31;i>=1;i--) {
            int t=((x>>(i-1))&1);
            if(siz[ch[q][t]]-siz[ch[p][t]]) {
                p=ch[p][t]; q=ch[q][t];
            }else {
                p=ch[p][!t]; q=ch[q][!t];
            }
        }
        return end[q];
    }
    void solve() {
        int i;
        for(i=1;i<n;i++) {
            int t=query(i+1,n,a[i]);
            q.push(A(i,t,i+1,n,a[i]^a[t]));
        }
        for(i=1;i<=K;i++) {
            A t=q.top(); q.pop();
            //printf("%d %d
    ",t.x,t.p);
            printf("%d ",a[t.x]^a[t.p]);
            int d;
            if(t.p>t.l) d=query(t.l,t.p-1,a[t.x]),q.push(A(t.x,d,t.l,t.p-1,a[d]^a[t.x]));
            if(t.p<t.r) d=query(t.p+1,t.r,a[t.x]),q.push(A(t.x,d,t.p+1,t.r,a[d]^a[t.x]));
        }
    }
    int main() {
        n=rd(); K=rd();
        int i;
        for(i=1;i<=n;i++) {
            a[i]=rd();
            insert(i);
        }
        solve();
    }
    
  • 相关阅读:
    slim中返回结果加密的
    windows下的redis和redismyadmin
    centos6.2升级到centos6.8(6.5应该也一样)
    剑指offer-二叉树的深度
    leetcode-【hard】4. Median of Two Sorted Arrays
    leetcode-【中等题】5. Longest Palindromic Substring
    leetcode-【中等题】3. Longest Substring Without Repeating Characters
    leetcode-【中等题】2. Add Two Numbers
    leetcode-【中等题】228. Summary Ranges
    leetcode-【hard】273. Integer to English Words
  • 原文地址:https://www.cnblogs.com/suika/p/9022824.html
Copyright © 2011-2022 走看看