BZOJ 3689: 异或之

二次联通门 : BZOJ 3689: 异或之

/*
    BZOJ 3689: 异或之

    zz题
*/
#include <cstdio>
#include <iostream>
#include <queue>
#define rg register
struct IO
{
    static const int BUF = 12323233;
    char p[BUF], *s, *t, e[BUF]; int a[25];
    IO () : s (p), t (e) { fread (s, 1, BUF, stdin); }
    ~IO () { fwrite (e, 1, t - e, stdout); }
    operator int ()
    {
        rg int j = 1, v = 0;
        for (; *s < 48; j = *s ++ ^ 45);
        do v = v * 10 + *s ++ - 48; while (*s >= 48);
        return j ? v : -v;
    }

    void pt (int v)
    {
        static int *q = a;
        if (!v) *t ++ = 48;
        else
        {
            if (v < 0) *t ++ = 45, v *= -1;

            for (; v; *q ++ = v % 10 + 48, v /= 10);
            for (; q != a; *t ++ = *-- q);
        }
        *t ++ = ‘ ‘;
    }
} ip;

#define Max 200203
int tr[Max * 20][2], TC, s[Max * 20];

void In (int key)
{
    int n = 0;
    for (rg int t, i = 30; i >= 0; -- i)
    {
        t = (key >> i) & 1;
        if (!tr[n][t]) tr[n][t] = ++ TC;
        n = tr[n][t], ++ s[n];
    }
}

int Ask (int key, int k)
{
    int res = 0, n = 0;
    for (rg int i = 30, t; i >= 0; -- i)
    {
        t = (key >> i) & 1;
        if (s[tr[n][t]] >= k) n = tr[n][t];
        else k -= s[tr[n][t]], n = tr[n][t ^ 1], res += (1 << i);
    }
    return res;
}
struct D
{
    int key, rk, x; 

    D (int a = 0, int b = 0, int c = 0) : key (a), rk (b), x (c) {}

    bool operator < (const D &rhs) const
    { return x > rhs.x; }
};

int a[Max];
std :: priority_queue <D> Q;

int main (int argc, char *argv[])
{
    int N = ip, K = ip; rg int i; D n;

    for (i = 1; i <= N; ++ i) a[i] = ip, In (a[i]);

    for (i = 1; i <= N; ++ i) Q.push (D (a[i], 2, Ask (a[i], 2)));

    for (i = 1; i < (K << 1); ++ i)
    {
        n = Q.top (), Q.pop ();
        if (i & 1) ip.pt (n.x);
        ++ n.rk, n.x = Ask (n.key, n.rk), Q.push (n);
    }
    return 0;
}
时间: 2024-08-30 00:24:48

BZOJ 3689: 异或之的相关文章

BZOJ 3689 异或 Trie木+堆

标题效果:特定n的数量,这种需求n数22 XOR的值前者k少 首先,我们建立了一个二进制的所有数字Trie木,您可以使用Trie木size域检查出一些其他的数字XOR值首先k少 然后,我们要保持一个堆.其他XOR的整数值首先2增加堆(第一小是自己异或自己.不在题目要求范围内).当取出一个数异或值的第k小后,将第k+1小增加堆 一个异或值会被两个数分别取出一次.所以取出奇数次时输出,取2*k次就可以 时间复杂度O(nlogn) #include<cstdio> #include<cstri

BZOJ 3689 异或之 Trie树+堆

题目大意:给定n个数,求这n个数两两异或的值中的前k小 首先我们对所有数字建立二进制Trie树,可以利用Trie树上的size域查询出一个数与其它数异或值的第k小 然后我们维护一个堆,将所有数与其它异或值的第2小加入堆(第一小是自己异或自己,不在题目要求范围内),当取出一个数异或值的第k小后,将第k+1小加入堆 一个异或值会被两个数分别取出一次,所以取出奇数次时输出,取2*k次即可 时间复杂度O(nlogn) #include<cstdio> #include<cstring> #

bzoj 2466 异或方程组

对于每个灯,我们用一个变量表示其决策,xu=0表示不选,xu=1表示选.因为每个灯最后必须都亮,所以每个等都对应一个异或方程. 解这个异或方程组,有几种情况: 1.存在唯一解(得到的上三角系数矩阵的主对角线上的元素全部为1) 2.存在v个自由元(即主对角线上有v个0) 我们枚举每个自由元的取值,有2v种情况,每种情况又分为 2.1.合法 2.2.不合法 (出现除以0的情况) 我们统计所有合法解的最小的值作为答案. 1 /**************************************

bzoj 4671: 异或图

4671: 异或图 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 61  Solved: 39[Submit][Status][Discuss] Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 G 中. 现在给定 s 个结点数相同的图 G1...s, 设 S = {G1, G2, .

bzoj 4671 异或图 —— 容斥+斯特林反演+线性基

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4671 首先,考虑容斥,就是设 \( t[i] \) 表示至少有 \( i \) 个连通块的方案数: 我们希望得到恰好有一个连通块的方案数,但这里不能直接 \( + t[1] - t[2] + t[3] - t[4] ... \),因为每个"恰好 \( i \) 个连通块"的情况并不是在各种 \( t[j] ( j<=i ) \) 中只被算了一次,而是因为标号,被算了 \(

[Strings]一些字符串题目

Trie BZOJ 3689 异或之 大意: 给定n个数,求这n个数两两异或的值中的前k小 解: 将加法换成异或就变成了一个用堆合并多个有序表的经典问题,对于加法我们按大小排序就能得到有序表,而由于这里是异或,我们需要高效地维护有序表,即对于一个数ai快速求出与它异或第k小的数. 我们将所有数按二进制建成Trie,然后在Trie的结点上记录下子树中的结束结点个数,再在Trie树上走一遍就得到了答案 BZOJ 3439 Kpm的MC密码 大意: 给定n个字符串,对于每个字符串求以这个字符串为后缀的

[省选]省选知识点进度

联赛之后记录一下自己的知识点学习情况(按开始时间先后顺序) 可持久化数据结构 [BZOJ 3123]森林 树上主席树 启发式合并 LCA [BZOJ 4826]影魔 区间修改主席树 标记永久化 [BZOJ 2735]世博会 主席树 切比雪夫距离转曼哈顿距离 [BZOJ 3166]Alo 可持久化01Trie [BZOJ 3689]异或之 可持久化01Trie [BZOJ 3261]最大异或和 可持久化01Trie 树套树 [COGS 257]动态排名系统 树状数组套主席树 [BZOJ 2141]

【BZOJ】【3261】最大异或和

可持久化Trie 嗯……同样搞个前缀异或和,然后将x与sum异或一下,就是在[l-1,r-1]中找x^sum的最大异或值了.同样可持久化Trie搞搞即可(模板还是没背全啊……sad 1 /************************************************************** 2 Problem: 3261 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:3888 ms 7 Memory:2395

BZOJ 3261: 最大异或和 [可持久化Trie]

3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1513  Solved: 657[Submit][Status][Discuss] Description 给定一个非负整数序列 {a},初始长度为 N.       有   M个操作,有以下两种操作类型: 1 .A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2 .Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得: a[p]