线段树应用:线段覆盖

线段覆盖

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 206            测试通过 : 57 

比赛描述

给出数轴上N条线段,每条线段用两个数表示A,B(-10^9<=A<B<=10^9),表示从a到b的一条线段。

现在请你求出它们覆盖数轴上的多长距离。



输入

第一行:N

以后N行,每行给出一条线段,即两个用空格隔开的整数:Ai和Bi

输出

个数,表示覆盖长度

样例输入

3
2 8
-1 1
5 10

样例输出

10

代码(不完全适合本题)

#include<iostream>
using namespace std;
 
/* 线段树求线段覆盖长度 */
#define BORDER 100 // 设线段端点坐标不超过100
 
struct Node         // 线段树
{
    int left;
    int right;
    int isCover;    // 标记是否被覆盖
}segTree[4*BORDER];
 
/* 构建线段树 根节点开始构建区间[lef,rig]的线段树*/
void construct(int index, int lef, int rig)
{
    segTree[index].left = lef;
    segTree[index].right = rig;
    if(rig - 1 == lef)                 // 到单位1线段
    {
        segTree[index].isCover = 0;
        return;
    }
    int mid = (lef+rig) >> 1;
    construct((index<<1)+1, lef, mid);
    construct((index<<1)+2, mid, rig); // 非mid+1,线段覆盖[mid,mid+1]
    segTree[index].isCover = 0;
}
 
/* 插入线段[start,end]到线段树, 同时标记覆盖 */
void insert(int index, int start, int end)
{
    if(segTree[index].isCover == 1) return; // 如已覆盖,没必要继续向下插
 
    if(segTree[index].left == start && segTree[index].right == end)
    {
        segTree[index].isCover = 1;
        return;
    }
    int mid = (segTree[index].left + segTree[index].right) >> 1;
    if(end <= mid)
    {
        insert((index<<1)+1, start, end);
    }else if(start >= mid)             // 勿漏=
    {
        insert((index<<1)+2, start, end);
    }else
    {
        insert((index<<1)+1, start, mid);
        insert((index<<1)+2, mid, end);
        // 注:不是mid+1,线段覆盖,不能漏[mid,mid+1]
    }
}
 
/* 计算线段覆盖长度 */
int Count(int index)
{
    if(segTree[index].isCover == 1)
    {
        return segTree[index].right - segTree[index].left;
    }else if(segTree[index].right - segTree[index].left == 1)
    {
        return 0;
    }
    return Count((index<<1)+1) + Count((index<<1)+2);
}

 
void main()
{
	int n;
	cin>>n;
    construct(0,-100,100);           // 构建[0,100]线段树
	int segment[100][2];
	for(int i=0;i<n;i++)
		cin>>segment[i][0]>>segment[i][1];
    for(int i = 0; i < n; ++i)   // 插入测试线段
    {
        insert(0,segment[i][0],segment[i][1]);
    }
    printf("the cover length is %d\n", Count(0));
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值