现在的位置: 首页 > 综合 > 正文

线段树

2013年01月17日 ⁄ 综合 ⁄ 共 1617字 ⁄ 字号 评论关闭

先看下线段树的介绍,下面这个链接讲得还不错 http://hi.baidu.com/semluhiigubbqvq/item/be736a33a8864789f4e4ad18

本文所讲的线段树和该文有微小区别,在该文中节点[0, 7]的左儿子为[0,3],右儿子为[4,7],不包含mid,而我们的线段树是包含的,即昨儿子为[0,3],右儿子为[3,7]。

现在我们用线段树解决以下问题(小米笔试题):

给定n个线段,每个线段告诉起点和终点,求线段总长度和,重合的部分只算一次。例如[0,3],[2,5],线段长度总和为[0,5]为5。实现代码如下:

#include <iostream>

using namespace std;

struct node
{
    int left;
    int right;
    int cover;
    node()
    {
        cover = 0;
    }
};

class LineSegmentTree
{
    private:
    node *tree;
    public:
    LineSegmentTree() {};
    LineSegmentTree(int left, int right);
    ~LineSegmentTree();
    void init(int left, int right, int root);
    void insert(int left, int right, int root=1);
    int sum(int root=1);
};

LineSegmentTree:: LineSegmentTree(int left, int right)
{
    tree = new node[(right-left)*3]();
    init(left, right, 1);
}

void LineSegmentTree:: init(int left, int right, int root)
{
    tree[root].left = left;
    tree[root].right = right;
    if(right - left == 1)
    {
        return;
    }
    int mid = (left + right) / 2;
    init(left, mid, 2*root);
    init(mid, right, 2*root+1);
}

void LineSegmentTree:: insert(int left, int right, int root)
{
    if(right <= left)
    {
        return;
    }
    if(left == tree[root].left && right == tree[root].right)
    {
        tree[root].cover++;
        return;
    }
    int mid = (tree[root].right + tree[root].left) / 2;
    if(mid >= right)
    {
        insert(left, right, 2*root);
    }
    else if(mid <= left)
    {
        insert(left, right, 2*root+1);
    }
    else
    {
        insert(left, mid, 2*root);
        insert(mid, right, 2*root+1);
    }
}

int LineSegmentTree:: sum(int root)
{
    if(tree[root].cover >= 1)
    {
        return tree[root].right - tree[root].left;
    }
    else if(tree[root].right - tree[root].left == 1)
    {
        return 0;
    }
    else
    {
        return sum(2*root) + sum(2*root+1);
    }
}

LineSegmentTree:: ~LineSegmentTree()
{
    delete[] tree;
}

int main()
{
    LineSegmentTree t(1, 15);
    t.insert(1, 4);
    t.insert(3, 5);
    t.insert(2, 6);
    t.insert(3, 5);
    t.insert(2, 3);
    t.insert(12, 13);
    t.insert(8, 13);
    cout<<t.sum()<<endl;
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.