区间覆盖(线段树)

区间覆盖(线段树)

X轴上方有若干条平行于X轴的线段,求这些线段能够覆盖X轴的总长度?

输入格式

第一行一个数n(n<=100000),表示线段个数;

接下来n行,每行两个整数a[i],b[i](-10^8<=a[i],b[i]<=10^8),代表一个线段的两个端点输出覆盖X轴的长度

输入样例

2

10 12

2 4

输出样例

4

 1 /*
 2 样例:
 3 有两段线
 4 1 2
 5 2 3
 6 */
 7
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 void print();
11 struct node{
12     int start,end;
13     int cover;
14 }segTree[100];
15
16 //创建线段树
17 void build(int root,int start,int end){
18     segTree[root].start=start;
19     segTree[root].end=end;
20     segTree[root].cover=0;
21     if(start+1<end){
22         int mid=(start+end)/2;
23         build(2*root,start,mid);
24         build(2*root+1,mid,end);
25     }
26 }
27
28 //1-4怎么办
29 //插入线段,线段的左右端点分别为left和right
30 void insert(int root,int left,int right){
31     //这里还是空的才需要插入
32     if(segTree[root].cover==0){
33         int mid=(segTree[root].start+segTree[root].end)/2;
34         if(left==segTree[root].start&&right==segTree[root].end){
35             segTree[root].cover=1;
36         }
37         else if(right<mid){//去左子树中找
38             insert(2*root,left,right);
39         }
40         else if(left>mid){//去右子树中找
41             insert(2*root+1,left,right);
42         }
43         else{//如果没有正好合适的,就把区间给拆了
44             insert(2*root,left,mid);
45             insert(2*root+1,mid,right);
46         }
47     }
48 }
49
50
51 int count(int root){
52     if(segTree[root].cover==1){
53         return segTree[root].end-segTree[root].start;
54     }
55     //又不等于1,又是叶子节点,肯定给你退出
56     else if(segTree[root].end-segTree[root].start==1){
57         return 0;
58     }
59     else{
60         return count(2*root)+count(2*root+1);
61     }
62 }
63
64 int main(){
65     build(1,1,5);
66     print();
67     insert(1,1,4);
68     //insert(1,2,3);
69     print();
70     //cout<<count(1)<<endl;
71     return 0;
72 }
73
74 void print(){
75     for(int i=1;i<=7;i++){
76         cout<<segTree[i].start<<" "<<segTree[i].end<<" "<<segTree[i].cover<<endl;
77     }
78     cout<<"-------------------------------------------------------------------------"<<endl;
79 }
时间: 2024-12-23 23:54:21

区间覆盖(线段树)的相关文章

hdu 5700区间交(线段树)

区间交 Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 849    Accepted Submission(s): 377 Problem Description 小A有一个含有n个非负整数的数列与m个区间.每个区间可以表示为li,ri. 它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大. 例如样例中,选择[2,5]

【区间合并线段树】BZOJ1593-安排住宿

[题目大意] 查询最左端的连续长度区间:或批量修改一些区间.[思路] 区间合并线段树……复习一下.POJ上有一样的题目,我居然还借用了别人的权限号去做BZOJ,简直愚昧到没朋友[笑cry] 处理方法以前的博文里有,这里有不赘述了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 using

POJ 2528 Mayor&#39;s posters 区间离散化线段树

点击打开链接 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45894   Accepted: 13290 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elector

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

poj3468A Simple Problem with Integers区间和线段树

同上... #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include

[UOJ #222][NOI2016]区间(线段树)

Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri. 对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度.区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值 求所有合法方案中最小的花费.如果不存在合法的方案,输出 −1. S

线段覆盖 (线段树)

有一根长度为 \(L\) 的白色条状物.有两种操作: 用一条长度为 \(T\) 的黑布盖住条状物的 \([a,a+T]\) 的这个区间 把某条黑布拿走 输入 \(L\) 和 \(n\) 次操作,要你输出每次操作之后 条状物上有多少个黑区间 条状物上黑区间的总长度 观察出题目的询问每次都是一样的,其实也只有一种修改(添和删相当于互逆操作) 我们可以建一棵线段树 \(v\) 表示有多少个黑区间 \(len\) 表示黑区间的总长度 \(tag\) 表示该区间添加的整布条数 显然答案就是线段树的根节点的

WHYZOJ-#53 线段树区间修改(线段树)

[题目描述]: 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 [输入描述]: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 [输出描述]: 输出包含若干行整

HDU 5700 区间交 线段树暴力

枚举左端点,然后在线段树内,更新所有左边界小于当前点的区间的右端点,然后查线段树二分查第k大就好 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int N = 100005; LL a[N]; struct Node{ int l,r; bool operator<(const Node &