HackerRank - "XOR key"

New techniques learnt: Trie can be used for some XOR problems. The basic idea: we build a MSB->LSB prefix Trie of all numbers; then query greedily: find an existing XOR-diff bit at each target bit index.

I found a clean and easy-to-understand code on LeaderBoard, from user pedrosorio

#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <set>
#include <string>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;

#define MAX_NODE 100000
#define MAX_MASK 32768

struct Node
{
    vector<int> inxes;
    Node *child[2]; // 0 - left, 1 - right
    Node()
    {
        child[0] = child[1] = nullptr;
    }
};

void insert(Node *root, int val, int inx)
{
    int mask = 1 << 14;
    int branch;
    Node *p = root;
    while (mask > 0)
    {
        branch = (mask & val) ? 1 : 0;
        if (p->child[branch] == nullptr)
            p->child[branch] = new Node();
        p = p->child[branch];
        p->inxes.push_back(inx);
        mask >>= 1;
    }
}

void treeDelete(Node *root)
{
    if (root)
    {
        treeDelete(root->child[0]);
        treeDelete(root->child[1]);
        delete root;
    }
}

//    If any existed index in inds is within [p, q]
bool inRange(vector<int> &inds, int p, int q)
{
    int min = 0, max = inds.size() - 1;
    int vmin = inds[min], vmax = inds[max];

    int mid, vmid;
    if (vmin > q || vmax < p) return false;
    if (vmin >= p || vmax <= q) return true;

    //    Binary search
    //    we need it, because [p,q] may fall into a gap
    while (max > min + 1)
    {
        mid  = (max + min) / 2;
        vmid = inds[mid];
        if (vmid < p)
            min = mid;
        else if (vmid > q)
            max = mid;
        else
            return true;
    }

    return false;
}

int treeMaxOr(Node *root, int a, int p, int q)
{
    int mask = 1 << 14, branch, ret = 0;
    Node *ptr = root;
    while (mask > 0)
    {
        branch = (mask & a) ? 0 : 1;
        if (ptr->child[branch] &&
            inRange(ptr->child[branch]->inxes, p, q))
        {
            ret += mask; // found a diff.
        }
        else
        {
            branch = 1 - branch;
        }
        ptr = ptr->child[branch];
        mask >>= 1;
    }
    return ret;
}

int main()
{
    int t; cin >> t;
    while (t--)
    {
        Node *root = new Node();
        int n, q; cin >> n >> q;
        for (int i = 0; i < n; i++)
        {
            int x; cin >> x;
            insert(root, x, i + 1);
        }
        while (q--)
        {
            int a, p, q; cin >> a >> p >> q;
            cout << treeMaxOr(root, a, p, q) << endl;
        }
        treeDelete(root);
    }
    return 0;
}

A more important lesson learnt: visualize the procdure in your mind, and you will probably close to the smart solution!

时间: 2024-10-10 04:16:25

HackerRank - "XOR key"的相关文章

51nod 1295 XOR key (可持久化Trie树)

1295 XOR key  题目来源: HackerRank 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题 给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少? Input 第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= 

[51nod 1295]Xor key(可持久化trie)

[51nod 1295]Xor key(可持久化trie) 题面 给出一个长度为n的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少? 分析 可持久化trie裸题 代码 #include<iostream> #include<cstdio> #define maxb 31 #define maxn 200000 #define maxs 6

51Nod - 1295:XOR key (可持久化Trie求区间最大异或)

给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?Input第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000). 第2 - N+1行:每行1个数,对应数组A的元素(0 <= Aii <= 10^9). 第N+2 - N+Q+1行:

【函数式Trie】51NOD 1295 XOR key

通道 思路:每个数建个31位的树,处理好关系即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 60007; const int BIT = 32; int n, m; int tot, s[N * BIT], a[N * BIT][2], root[N]; void Insert(int x, int &y, in

x64 QWORD Xor shellcode encoder

#!/usr/bin/env python #Filename: Xor_QWORD_x64.py #coding=utf-8 import re import sys import random import struct class QWORDXorEncoder: def __init__(self): self.name = "x64 QWORD Xor Encoder" self.description = "x64 QWORD Xor shellcode enco

DES加密解密的C++源程序

DES加密解密的C++源程序 --测试版本,希望大家多多交流 #include<iostream.h> #include"stdio.h" #include"math.h" #include "string.h" static char key[16][48]; static char Hex[16][4]; ////IP置换. int IP[64]= { 58,50,42,34,26,18,10,2,\ 60,52,44,36,28

IDA的脚本IDC的一个简单使用

目的:主要是想学习一下IDA的IDC的脚本的使用.这里做了一个小的测试. 这里使用的是VS2015Community来生成文件的. 一.编写测试程序: #include <stdio.h> #include <string.h> //the xor key is 'B' ,异或的key int Verify(char *Flag) { int i; int tar[10] = { 00, 43, 44, 29, 14, 47, 47, 10, 29, 1 }; //这里是关键数据

MD5和SHA1算法C++实现及运行时间分析

1.MD5代码实现 HMAC.H即MD5头文件. #ifndef HMAC_H #define HMAC_H // POINTER defines a generic pointer type typedef unsigned char *POINTER; // UINT2 defines a two byte word typedef unsigned short int UINT2; // UINT4 defines a four byte word typedef unsigned lon

可逆加密解密单元文件和调用方法

1 (**************************************************) 2 (* *) 3 (* Advanced Encryption Standard (AES) *) 4 (* Interface Unit v1.3 *) 5 (* *) 6 (* *) 7 (* Copyright (c) 2002 Jorlen Young *) 8 (* *) 9 (* *) 10 (* *) 11 (*说明: *) 12 (* *) 13 (* 基于 ElASE