• 线段树+离散化 IP地址段检查 SEGMENT TREE


    Problem:

    Give a series of IP segments, for example, [0.0.0.1-0.0.0.3], [123.234.232.21-123.245.21.1]...

    Now there is a new IP, find which IP segment it's in ?

    Solution:

    First, we could map the ends of IP segments into some intervals, since the IP address could be represented by a unsigned int. This is called discretization

    Second, setup the segment tree. Every leaf node is [x, x+1], it means whether an IP segment includes the part. We could use a vector<int> to record the interval index for searching. So the core code is:

    #include <iostream>
    #include <map>
    #include <vector>
    #include <algorithm>
    #include <limits.h>
    #include <assert.h>
    #include <stdio.h>
    using namespace std;
    
    class Interval {
     public:
      int l, r;
      Interval(int ll = 0, int rr = 0) : l(ll), r(rr) {}
    };
    class Node {
     public:
      int l, r;
      Node *lc, *rc;
      vector<int> IPs;
      
      Node(int ll = 0, int rr = 0) : l(ll), r(rr), lc(NULL), rc(NULL) {}
    };
    
    Node* build(int l, int r) {
      Node *root = new Node();
      root->l = l, root->r = r;
      if (l + 1 >= r)
        return root;
      int mid = (l + r) / 2;
      root->lc = build(l, mid);
      root->rc = build(mid, r);
      return root;
    }
    void insert(Node* root, int l, int r, int idx) {
      if (l <= root->l && r >= root->r) {
        root->IPs.push_back(idx);
        return;
      }
      int mid = (root->l + root->r) / 2;
      if (l < mid) // Take care here!
        insert(root->lc, l, mid, idx);
      if (r > mid) // Take care here!
        insert(root->rc, mid, r, idx);
    }
    void search(Node* root, int l, int r, vector<int>& res) {
      if (r <= root->r && l >= root->l) {
        for (int i = 0; i < root->IPs.size(); ++i)
          res.push_back(root->IPs[i]);
      }
      int mid = (root->l + root->r) / 2;
      if (r <= mid)
        search(root->lc, l, mid, res);
      if (l >= mid)
        search(root->rc, mid, r, res);
    }
    int main()
    {
      Node* rt = build(1, 7);
      Interval inters[] = {Interval(1,3),Interval(2,4),Interval(1,5), Interval(5,7)};
      int size = sizeof(inters) / sizeof(inters[0]);
      for (int i = 0; i < size; ++i) 
        insert(rt, inters[i].l, inters[i].r, i);
      vector<int> res;
      search(rt, 2, 3, res);
      return 0;
    }



  • 相关阅读:
    我的大学生涯
    如何设计一个好的Windows 8应用
    [置顶] 十大高明的Google搜索技巧
    [置顶] 走出困境靠自己
    Android代码混淆前后分析
    百度高级搜索
    未来手机什么样 十款未来概念手机图赏
    如何看懂Java混淆后的反编译代码
    最值得一看的几条简单的谷歌 Google 搜索技巧,瞬间提升你的网络搜索能力!
    各种网页尺寸判断方法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7094253.html
Copyright © 2020-2023  润新知