zoukankan      html  css  js  c++  java
  • HackerRank

    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;
    }
    View Code

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

  • 相关阅读:
    BlangenOA项目总结
    ==和Equals与值类型和引用类型
    SQL Server索引
    Html5 之拖动
    Html5 之过渡
    Html 之登录界面
    Html 之进度条
    GUI 之密码框
    GUI 之文本框
    GUI 之列表框
  • 原文地址:https://www.cnblogs.com/tonix/p/4599698.html
Copyright © 2011-2022 走看看