蓝桥杯 校门外面的树 (线段树,区间处理)
2016-03-13 20:35
302 查看
问题描述
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数 轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已
知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树
都移走后,马路上还有多少棵树。
输入格式
输入文件的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <=
100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点
和终止点的坐标。
输出格式
输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例输入
500 3
150 300
100 200
470 471
样例输出
298
数据规模和约定
对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。
挺基础的一道线段树的题目,直接附上我的ac代码:
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数 轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已
知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树
都移走后,马路上还有多少棵树。
输入格式
输入文件的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <=
100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点
和终止点的坐标。
输出格式
输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例输入
500 3
150 300
100 200
470 471
样例输出
298
数据规模和约定
对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。
挺基础的一道线段树的题目,直接附上我的ac代码:
#include<iostream> using namespace std; struct node{ int l,r,w; }tree[50050]; void create(int i,int left,int right){ tree[i].l=left;tree[i].r=right; if(left==right){ tree[i].w=1; return; } int mid=(left+right)>>1; create(i<<1,left,mid); create((i<<1)|1,mid+1,right); tree[i].w=tree[i<<1].w+tree[(i<<1)|1].w; } void update(int i,int left,int right){ if(tree[i].l==tree[i].r){ tree[i].w=0;return; } if(tree[i].l==left&&tree[i].r==right){ tree[i].w=0;return; } if(tree[i].w==0) return; int mid=(tree[i].l+tree[i].r)>>1; if(right<=mid){ update(i<<1,left,right); }else if(left>mid){ update((i<<1)|1,left,right); }else{ update(i<<1,left,mid); update((i<<1)|1,mid+1,right); } tree[i].w=tree[i<<1].w+tree[(i<<1)|1].w; } int find(int i,int left,int right){ if(tree[i].w==0)return 0; if(left==right) return 1; if(tree[i].l==left&&tree[i].r==right){ return tree[i].w; } int mid=(tree[i].l+tree[i].r)>>1; if(right<=mid){ return find(i<<1,left,right); }else if(left>mid){ return find((i<<1)|1,left,right); }else{ return find(i<<1,left,mid)+find((i<<1)|1,mid+1,right); } } int main(){ int L,M,le,ri; cin>>L>>M; create(1,0,L); while(M--){ cin>>le>>ri; update(1,le,ri); } cout<<find(1,0,L)<<endl; return 0; }
相关文章推荐
- stl之关联容器——set,map,hashtable
- LeetCode101—Symmetric Tree
- 深入理解C++语言
- 数据结构――广义表
- Mac Android Studio 如何使用资产目录
- 关于沙盒路径的一些理解
- HDOJ 3743 Frosh Week(树状数组求逆序对)
- (原创)暴力破解西电校园网密码
- 数据库连接池
- java线程之间的通信(等待/通知机制)
- BZOJ_P4245 [ONTAK2015]OR-XOR
- terminal快捷键以及vim快捷键
- #164. 【清华集训2015】V
- KALI 2.0优化
- 构建之法阅读感想一
- 学习记录(一)
- 名言警句
- 104. Maximum Depth of Binary Tree
- 小球反弹问题
- CodeForces 622A--F - Infinite Sequence