zoukankan      html  css  js  c++  java
  • #3315. fullcombo

    题目描述

    SmallBell最近沉迷Lovelive,苦于[Beat In Angel]的fc。他在研究用什么队伍的时候,顺便把队伍的Cool属性也记录了下来,于是他得到 $n$ 个数。

    旁边的WerKeyTom_FTD正苦于如何卡常数。他突然对SmallBell提了个问题:选择两个数 $i,j$ $(i eq j)$ ,把第 $i,j$ 个数异或起来,求第 $k$ 大的异或值是多少。注意: $(i,j)$ 和 $(j,i)$ 是不同方案。

    SmallBell:好水啊,一下就切了!然后把问题交给了你。

    数据范围

    除 $k$ 外所有数为不大于 $5 imes 10^4$ 的正整数, $1 le k le n imes (n-1)$

    题解

    建立 $trie$ 树,考虑二分答案,然后每个数在 $trie$ 树上找出异或值 $≥mid$ 的个数总和,然后和 $k$ 判断即可,效率: $O(nlog^2n)$

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N=5e4+5;
    int n,a[N],l,r=(1<<16)-1,d,t=1;
    LL k;
    struct O{
        int ch[2],sz;
    }tr[N*50];
    void ins(int x){
        int p=1;
        for (int v,i=15;~i;i--){
            v=(x>>i)&1;
            if (!tr[p].ch[v])
                tr[p].ch[v]=++t;
            p=tr[p].ch[v];tr[p].sz++;
        }
    }
    int get(int x){
        int p=1,sum=0;
        for (int v,i=15;~i;i--){
            v=(x>>i)&1;
            if (d&(1<<i))
                p=tr[p].ch[v^1];
            else 
                sum+=tr[tr[p].ch[v^1]].sz,
                p=tr[p].ch[v];
        }
        return sum+tr[p].sz;
    }
    bool J(){
        LL sum=0;
        for (int i=1;i<=n;i++)
            sum+=1ll*get(a[i]);
        return (sum>=k);
    }
    int main(){
        scanf("%d%lld",&n,&k);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]),ins(a[i]);
        while(l<r){
            d=(l+r+1)>>1;
            if (J()) l=d;
            else r=d-1;
        }
        return printf("%d
    ",l),0;
    }
  • 相关阅读:
    javascript继承对象冒充
    javascript原型prototype(2)
    javascript继承call()和apply实现继承
    javascript继承原型链继承
    javascript原型prototype(3)
    没有宽高的情况下实现水平垂直居中
    TCP协议
    什么是模块化?模块化的好处是什么?
    数组中嵌套数组,转化为一个数组形式/二维数组转化为一维数组
    常见的请求头类型
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/11327028.html
Copyright © 2011-2022 走看看