LibreOJ #114. k 大异或和

二次联通门 : LibreOJ #114. k 大异或和

/*
    LibreOJ #114. k 大异或和

    WA了很多遍
    为什么呢。。。

    一开始读入原数的时候写的是for(;N--;)
    而重新构造线性基的时候要用到N。。。所以GG

    对于找第k大异或和
    只需把原来的线性基重新构造
    构造规则为
        若i<j, aj的第j位是1,就把aj异或上ai

    查询的时候将k二进制拆分,对于1的位,就异或上对应的线性基。
    最终得出的答案就是k小值。
*/
#include <cstring>
#include <cstdio>

inline void read (long long &now)
{
    register char word = getchar ();
    bool temp = false;
    for (now = 0; word < ‘0‘ || word > ‘9‘; word = getchar ())
        if (word == ‘-‘)
            temp = true;
    for (; word >= ‘0‘ && word <= ‘9‘; now = now * 10 + word - ‘0‘, word = getchar ());
    if (temp)
        now = -now;
}

long long N, M;

class Linear_Base_Type
{
    static const int _L = 52;

    private :

        long long number[_L + 2];
        long long data[_L + 2];

        int Count;

    public :

        Linear_Base_Type ()
        {
            memset (data, 0, sizeof data);
            memset (number, 0, sizeof number);
            Count = 0;
        }

        inline void Insert (register long long key)
        {
            for (register int i = _L; i >= 0; i --)
                if (key & (1LL << i))
                {
                    if (number[i] == 0)
                    {
                        number[i] = key;
                        break;
                    }
                    key ^= number[i];
                }
            return ;
        }

        void Re_Build ()
        {
            for (register int i = 1, j; i <= _L; i ++)
                for (j = 0; j < i; j ++)
                    if ((1LL << j) & number[i])
                        number[i] ^= number[j];

            for (register int i = 0; i <= _L; i ++)
                if (number[i])
                    data[Count ++] = number[i];
        }

        inline long long Query_kth (register long long k)
        {
            long long res = 0;

            if (Count != N)
                -- k;
            if (k >= (1LL << Count))
                return -1;

            for (register int i = 0; i <= _L; i ++)
                if (k & (1LL << i))
                    res ^= data[i];

            return res;
        }
};

Linear_Base_Type Make;

int main (int argc, char *argv[])
{
    long long x;
    read (N);

    for (int i = 1; i <= N; i ++)
    {
        read (x);

        Make.Insert (x);
    }
    read (M);
    for (Make.Re_Build (); M --; )
    {
        read (x);

        printf ("%lld\n", Make.Query_kth (x));
    }
    return 0;
}
时间: 2024-08-10 17:01:40

LibreOJ #114. k 大异或和的相关文章

[LOJ#114]k 大异或和

试题描述 这是一道模板题. 给由 n 个数组成的一个可重集 S,每次给定一个数 k,求一个集合 T?S,使得集合 T 在 S 的所有非空子集的不同的异或和中,其异或和 T1 xor T2 xor - xor T|T| 是第 k 小的. 输入 第一行一个数 n.第二行 n 个数,表示集合 S.第三行一个数 m,表示询问次数.第四行 m 个数,表示每一次询问的 k. 输出 输出 m 行,对应每一次询问的答案,第 k 小的异或和.如果集合 S 的所有非空子集中,不同的异或和数量不足 k,输出 -1.

hdu 3949 第k大异或组合

题意: 给你一些数,其中任选一些数(大于等于一个),那么他们有一个异或和. 求所有这样的异或和的第k小. 我们可以将每一位看成一维,然后就是给我们n个60维的向量,求它们线性组合后得到的向量空间中,第k小的向量. 因为给我们的向量不一定是非线性相关的(即存在一些向量可以被其他向量线性表示出),所以我们先进行异或高斯消元,将这n个数”精简出“一组基底,即精简前得到的向量空间和精简后的到的是一样的.(精简后最多有60个向量). 假如我们的到了m个基底,因为它们线性不相关,所以我们有2^m种可能(包括

51nod p1175 区间中第K大的数

1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 例如: 1 7 6 3 1.i = 1, j = 3,k = 2,对应的数为7 6 3,第2大的数为6. Input 第1行:1个数N,表示序列的长度.(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列中的元素.(0 <= S[i] <

POJ2761---Feed the dogs (Treap求区间第k大)

题意 就是求区间第k大,区间 不互相包含. 尝试用treap解决一下 第k大的问题. 1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <

POJ2104-- K-th Number(主席树静态区间第k大)

[转载]一篇还算可以的文章,关于可持久化线段树http://finaltheory.info/?p=249 无修改的区间第K大 我们先考虑简化的问题:我们要询问整个区间内的第K大.这样我们对值域建线段树,每个节点记录这个区间所包含的元素个数,建树和查询时的区间范围用递归参数传递,然后用二叉查找树的询问方式即可:即如果左边元素个数sum>=K,递归查找左子树第K大,否则递归查找右子树第K – sum大,直到返回叶子的值. 现在我们要回答对于区间[l, r]的第K大询问.如果我们能够得到一个插入原序

HDU 5249 离线树状数组求第k大+离散化

KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1160    Accepted Submission(s): 488 Problem Description 你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度.数十亿的请求被推到一个大管道后同时服务从管头拉取请求.让我们来定义每个请求都有一个重要值.我的

ZOJ2112--Dynamic Rankings (动态区间第k大)

Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They

1686 第K大区间

1686 第K大区间 时间限制:1 秒 空间限制:131072 KB 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 众数(统计学/数学名词)_百度百科 Input 第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31 Output 一个数表示答案. Input示例 4 2 1 2 3 2 Output示例 2思路:二分答案t,统计众数出现次数大于等于t的区间有多少个. 枚

zoj2112 主席树动态第k大 (主席树&amp;&amp;树状数组)

Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They