校门外的树 区间处理

来源:互联网 发布:linux配置路由表命令 编辑:程序博客网 时间:2024/04/29 14:22
问题描述
  某校大门外长度为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

解题思路:

线段树区间处理问题,顺便自己写了一个线段树当做练手了;

#include<cstdio>#include<cstring>#include<algorithm>#include<string>using namespace std;#define maxn 100000#define L(a) (a)<<1#define R(a) (a)<<1|1struct Node{int sum;int add;int set;int left,right;}node[3*maxn];int ans;int a,b;void create(int num,int l,int r){node[num].left=l;node[num].right=r;if(l==r){node[num].sum=1;node[num].set=-1;node[num].add=0;return ;}int mid=(l+r)>>1;create(L(num),l,mid);create(R(num),mid+1,r);node[num].sum=node[L(num)].sum+node[R(num)].sum;node[num].set=-1;node[num].add=0;}void maintain(int num,int l,int r){node[num].sum=1;if(r>l){node[num].sum=node[L(num)].sum+node[R(num)].sum;}}void pushup(int num){node[num].sum=node[L(num)].sum+node[R(num)].sum;}void pushdown(int num){if(node[num].set==0){node[L(num)].set=node[R(num)].set=node[num].set;node[L(num)].sum=0;node[R(num)].sum=0;node[num].set=-1;}}void updata(int num,int l,int r,int v){if(node[num].left==l&&node[num].right==r){node[num].set=v;node[num].sum=(r-l+1)*v;return ;}else{pushdown(num);int mid=(node[num].left+node[num].right)>>1;if(r<=mid)updata(L(num),l,r,v);else if(l>mid)updata(R(num),l,r,v);else{updata(L(num),l,mid,v);updata(R(num),mid+1,r,v);}pushup(num);}}void query(int num,int l,int r){if(node[num].left==l&&node[num].right==r){ans+=node[num].sum;return ;}int mid=(node[num].left+node[num].right)>>1;if(r<=mid)query(L(num),l,r);else if(l>mid)query(R(num),l,r);else{query(L(num),l,mid);query(R(num),mid+1,r);}}int main(){int n,m;scanf("%d%d",&n,&m);create(1,0,n);ans=0;for(int i=0;i<m;i++){scanf("%d%d",&a,&b);updata(1,a,b,0);}query(1,0,n);printf("%d\n",ans);}  


0 0
原创粉丝点击