zoukankan      html  css  js  c++  java
  • 区间覆盖(线段树)

    区间覆盖(线段树)

    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 }

    再贴一份代码,上面那段代码insert位置有问题

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct node{
     4     int val;
     5     int start;
     6     int end;
     7 }tree[100];
     8 
     9 void print();
    10 
    11 void build(int root,int start,int end){
    12     //这里是线段有没有覆盖,所以叶子节点是线段而不是点
    13     tree[root].start=start;
    14     tree[root].end=end;
    15     tree[root].val=0;
    16     if(start+1<end){
    17         int mid=(start+end)/2;
    18         build(2*root,start,mid);
    19         build(2*root+1,mid,end);
    20     } 
    21 }
    22 
    23 void insert(int root,int left,int right){
    24     if(tree[root].val==0){
    25         int start=tree[root].start;
    26         int end=tree[root].end;
    27         int mid=(start+end)/2;
    28         cout<<start<<" "<<end<<endl;
    29         if(start==left&&end==right){
    30             tree[root].val=1;
    31         }
    32         else if(start+1==end){
    33             return ;
    34         }
    35         else if(mid<left){
    36             insert(2*root+1,left,right);
    37         }
    38         else if(right<mid){
    39             insert(2*root,left,right);
    40         }
    41         else{
    42             insert(2*root,left,mid);
    43             insert(2*root+1,mid,right);
    44         }
    45     }    
    46 }
    47 
    48 int count(int root){
    49     int start=tree[root].start;
    50     int end=tree[root].end;
    51     int val=tree[root].val;
    52     if(val==1){
    53         return end-start;
    54     }
    55     else if(end-start==1){
    56         return 0;
    57     }
    58     else{
    59         return count(root*2)+count(root*2+1);
    60     }
    61 }
    62 
    63 int main(){
    64     build(1,1,5);
    65     print();
    66     insert(1,1,4);
    67     print();
    68     cout<<count(1)<<endl;
    69     return 0;
    70       
    71 } 
    72 
    73 void print(){
    74     for(int i=1;i<=7;i++){
    75         cout<<tree[i].start<<" "<<tree[i].end<<" "<<tree[i].val<<endl;
    76     }
    77     cout<<endl;
    78 }
  • 相关阅读:
    有关linux查看的命令 及本机yum创建
    linux系统命令1
    手机百度网盘加群方法
    百度网盘保存超限解决办法
    c#委托、泛型委托和匿名方法
    值类型和引用类型的总结
    SQL数据查询语句(一)
    c# Invoke和Begininvoke区别
    c#public、private、protected、internal、protected internal修饰符及访问权限
    C#之打印乘法表
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7507908.html
Copyright © 2011-2022 走看看